From b46ef9cbe60458c5bff0a771defd5277fc2a210b Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 29 May 2024 16:59:29 +0330 Subject: [PATCH] last ... --- .../Classes/x-saherelm.base.class.ex5 | Bin 0 -> 5488 bytes .../x-saherelm.x121.provider.class.ex5 | Bin 0 -> 10318 bytes .../Classes/x-saherelm.x121.xea.class.ex5 | Bin 0 -> 11604 bytes .../Classes/x-saherelm.x121.xmcycle.class.ex5 | Bin 0 -> 9632 bytes .../Classes/x-saherelm.x5.provider.class.ex5 | Bin 0 -> 9852 bytes .../Classes/x-saherelm.xaccount.class.ex5 | Bin 0 -> 6040 bytes .../Classes/x-saherelm.xalert.class.ex5 | Bin 0 -> 5586 bytes .../x-saherelm.xdata-collector.class.ex5 | Bin 0 -> 5682 bytes .../Classes/x-saherelm.xea.class.ex5 | Bin 0 -> 11836 bytes .../Classes/x-saherelm.xhelper.class.ex5 | Bin 0 -> 6160 bytes .../Classes/x-saherelm.xhttp.class.ex5 | Bin 0 -> 5362 bytes .../Classes/x-saherelm.xmd5.class.ex5 | Bin 0 -> 4348 bytes .../Classes/x-saherelm.xprovider.class.ex5 | Bin 0 -> 11150 bytes .../Classes/x-saherelm.xtrade.class.ex5 | Bin 0 -> 10990 bytes .../14030306 copy/Experts/x-test.x121ea.ex5 | Bin 0 -> 265056 bytes .../14030306 copy/Experts/x-test.x5121ea.ex5 | Bin 0 -> 227360 bytes .../Helpers/x-saherelm.xama.helper.ex5 | Bin 0 -> 5496 bytes .../Helpers/x-saherelm.xcc.helper.ex5 | Bin 0 -> 5900 bytes .../Helpers/x-saherelm.xche.helper.ex5 | Bin 0 -> 5674 bytes .../Helpers/x-saherelm.xchlh.helper.ex5 | Bin 0 -> 6310 bytes .../Helpers/x-saherelm.xchma.helper.ex5 | Bin 0 -> 5860 bytes .../Helpers/x-saherelm.xct.helper.ex5 | Bin 0 -> 5510 bytes .../Helpers/x-saherelm.xdon.helper.ex5 | Bin 0 -> 6180 bytes .../Helpers/x-saherelm.xfi.helper.ex5 | Bin 0 -> 5516 bytes .../Helpers/x-saherelm.xhk.helper.ex5 | Bin 0 -> 5592 bytes .../Helpers/x-saherelm.xhull.helper.ex5 | Bin 0 -> 6228 bytes .../Helpers/x-saherelm.xich.helper.ex5 | Bin 0 -> 5794 bytes .../Helpers/x-saherelm.xlh.helper.ex5 | Bin 0 -> 5600 bytes .../Helpers/x-saherelm.xmc.helper.ex5 | Bin 0 -> 6412 bytes .../Helpers/x-saherelm.xmrb.helper.ex5 | Bin 0 -> 5944 bytes .../Helpers/x-saherelm.xobd.helper.ex5 | Bin 0 -> 6832 bytes .../Helpers/x-saherelm.xosc.helper.ex5 | Bin 0 -> 5902 bytes .../Helpers/x-saherelm.xpv.helper.ex5 | Bin 0 -> 6872 bytes .../Helpers/x-saherelm.xrsi.helper.ex5 | Bin 0 -> 5720 bytes .../Helpers/x-saherelm.xsslc.helper.ex5 | Bin 0 -> 5366 bytes .../Helpers/x-saherelm.xstr.helper.ex5 | Bin 0 -> 5486 bytes .../Helpers/x-saherelm.xtd.helper.ex5 | Bin 0 -> 5250 bytes .../Helpers/x-saherelm.xtm.helper.ex5 | Bin 0 -> 5242 bytes .../Helpers/x-saherelm.xts.helper.ex5 | Bin 0 -> 5718 bytes .../Helpers/x-saherelm.xzg.helper.ex5 | Bin 0 -> 6336 bytes .../Indicators/x-saherelm.xama.ex5 | Bin 0 -> 13490 bytes .../Indicators/x-saherelm.xcc.ex5 | Bin 0 -> 11746 bytes .../Indicators/x-saherelm.xche.ex5 | Bin 0 -> 17584 bytes .../Indicators/x-saherelm.xchlh.ex5 | Bin 0 -> 48034 bytes .../Indicators/x-saherelm.xchma.ex5 | Bin 0 -> 48370 bytes .../Indicators/x-saherelm.xct.ex5 | Bin 0 -> 17390 bytes .../Indicators/x-saherelm.xdon.ex5 | Bin 0 -> 12282 bytes .../Indicators/x-saherelm.xfi.ex5 | Bin 0 -> 9800 bytes .../Indicators/x-saherelm.xhk.ex5 | Bin 0 -> 14466 bytes .../Indicators/x-saherelm.xhull.ex5 | Bin 0 -> 17748 bytes .../Indicators/x-saherelm.xich.ex5 | Bin 0 -> 21726 bytes .../Indicators/x-saherelm.xlh.ex5 | Bin 0 -> 14786 bytes .../Indicators/x-saherelm.xmc.ex5 | Bin 0 -> 17750 bytes .../Indicators/x-saherelm.xmrb.ex5 | Bin 0 -> 21534 bytes .../Indicators/x-saherelm.xobd.ex5 | Bin 0 -> 16784 bytes .../Indicators/x-saherelm.xosc.ex5 | Bin 0 -> 24598 bytes .../Indicators/x-saherelm.xpv.ex5 | Bin 0 -> 56216 bytes .../Indicators/x-saherelm.xrsi.ex5 | Bin 0 -> 16820 bytes .../Indicators/x-saherelm.xsslc.ex5 | Bin 0 -> 14512 bytes .../Indicators/x-saherelm.xstr.ex5 | Bin 0 -> 12730 bytes .../Indicators/x-saherelm.xtd.ex5 | Bin 0 -> 15400 bytes .../Indicators/x-saherelm.xtm.ex5 | Bin 0 -> 13866 bytes .../Indicators/x-saherelm.xts.ex5 | Bin 0 -> 36332 bytes .../Indicators/x-saherelm.xzg.ex5 | Bin 0 -> 12442 bytes .../Libraries/x-saherelm.common.lib.ex5 | Bin 0 -> 5216 bytes .../Libraries/x-saherelm.draw.lib.ex5 | Bin 0 -> 6092 bytes .../Libraries/x-saherelm.xtrade.lib.ex5 | Bin 0 -> 8016 bytes .../Classes/x-saherelm.base.class.mq5 | 88 + .../x-saherelm.x121.provider.class.mq5 | 10928 ++++++++++++++++ .../Classes/x-saherelm.x121.xea.class.mq5 | 1811 +++ .../Classes/x-saherelm.x121.xmcycle.class.mq5 | 7380 +++++++++++ .../Classes/x-saherelm.xaccount.class.mq5 | 398 + .../Classes/x-saherelm.xalert.class.mq5 | 1363 ++ .../x-saherelm.xdata-collector.class.mq5 | 481 + .../14030309/Classes/x-saherelm.xea.class.mq5 | 4041 ++++++ .../Classes/x-saherelm.xhelper.class.mq5 | 148 + .../Classes/x-saherelm.xhttp.class.mq5 | 373 + .../Classes/x-saherelm.xmd5.class.mq5 | 441 + .../Classes/x-saherelm.xprovider.class.mq5 | 267 + .../Classes/x-saherelm.xtrade.class.mq5 | 3692 ++++++ .../BKPS/14030309/Experts/x-test.x121ea.mq5 | 1011 ++ .../Helpers/x-saherelm.xama.helper.mq5 | 317 + .../Helpers/x-saherelm.xcc.helper.mq5 | 245 + .../Helpers/x-saherelm.xche.helper.mq5 | 514 + .../Helpers/x-saherelm.xchlh.helper.mq5 | 967 ++ .../Helpers/x-saherelm.xchma.helper.mq5 | 960 ++ .../Helpers/x-saherelm.xct.helper.mq5 | 220 + .../Helpers/x-saherelm.xdon.helper.mq5 | 1075 ++ .../Helpers/x-saherelm.xfi.helper.mq5 | 292 + .../Helpers/x-saherelm.xhk.helper.mq5 | 1014 ++ .../Helpers/x-saherelm.xhull.helper.mq5 | 399 + .../Helpers/x-saherelm.xich.helper.mq5 | 827 ++ .../Helpers/x-saherelm.xlh.helper.mq5 | 422 + .../Helpers/x-saherelm.xmc.helper.mq5 | 496 + .../Helpers/x-saherelm.xmrb.helper.mq5 | 1411 ++ .../Helpers/x-saherelm.xobd.helper.mq5 | 306 + .../Helpers/x-saherelm.xosc.helper.mq5 | 1321 ++ .../Helpers/x-saherelm.xpv.helper.mq5 | 1870 +++ .../Helpers/x-saherelm.xrsi.helper.mq5 | 392 + .../Helpers/x-saherelm.xsslc.helper.mq5 | 408 + .../Helpers/x-saherelm.xstr.helper.mq5 | 421 + .../Helpers/x-saherelm.xtd.helper.mq5 | 458 + .../Helpers/x-saherelm.xtm.helper.mq5 | 310 + .../Helpers/x-saherelm.xts.helper.mq5 | 550 + .../Helpers/x-saherelm.xzg.helper.mq5 | 527 + .../14030309/Indicators/x-saherelm.xama.mq5 | 348 + .../14030309/Indicators/x-saherelm.xcc.mq5 | 458 + .../14030309/Indicators/x-saherelm.xche.mq5 | 631 + .../14030309/Indicators/x-saherelm.xchlh.mq5 | 816 ++ .../14030309/Indicators/x-saherelm.xchma.mq5 | 1134 ++ .../14030309/Indicators/x-saherelm.xct.mq5 | 261 + .../14030309/Indicators/x-saherelm.xdon.mq5 | 366 + .../14030309/Indicators/x-saherelm.xfi.mq5 | 309 + .../Indicators/x-saherelm.xfi.osc.mq5 | 309 + .../14030309/Indicators/x-saherelm.xhk.mq5 | 479 + .../14030309/Indicators/x-saherelm.xhull.mq5 | 583 + .../14030309/Indicators/x-saherelm.xich.mq5 | 846 ++ .../14030309/Indicators/x-saherelm.xlh.mq5 | 352 + .../14030309/Indicators/x-saherelm.xmc.mq5 | 446 + .../14030309/Indicators/x-saherelm.xmrb.mq5 | 855 ++ .../14030309/Indicators/x-saherelm.xobd.mq5 | 392 + .../14030309/Indicators/x-saherelm.xosc.mq5 | 721 + .../14030309/Indicators/x-saherelm.xpv.mq5 | 1211 ++ .../14030309/Indicators/x-saherelm.xrsi.mq5 | 394 + .../14030309/Indicators/x-saherelm.xsslc.mq5 | 440 + .../14030309/Indicators/x-saherelm.xstr.mq5 | 580 + .../14030309/Indicators/x-saherelm.xtd.mq5 | 457 + .../Indicators/x-saherelm.xtd.osc.mq5 | 457 + .../14030309/Indicators/x-saherelm.xtm.mq5 | 351 + .../14030309/Indicators/x-saherelm.xts.mq5 | 548 + .../14030309/Indicators/x-saherelm.xzg.mq5 | 750 ++ .../BKPS/14030309/JsModules/x-color.tools.js | 506 + .../BKPS/14030309/JsModules/x-file.tools.js | 890 ++ .../BKPS/14030309/JsModules/x-shell.tools.js | 219 + .../JsModules/x-type-detector.tools.js | 268 + .../BKPS/14030309/JsModules/x-value.tools.js | 1528 +++ .../Libraries/x-saherelm.common.lib.mq5 | 7165 ++++++++++ .../Libraries/x-saherelm.draw.lib.mq5 | 2443 ++++ .../Libraries/x-saherelm.xtrade.lib.mq5 | 4167 ++++++ MQLTestWorkspace/BKPS/14030309/compile.js | 427 + MQLTestWorkspace/BKPS/14030309/pack.js | 86 + MQLTestWorkspace/BKPS/14030309/package.json | 43 + MQLTestWorkspace/BKPS/SingallingXTDNew.mq5 | 415 + 143 files changed, 80795 insertions(+) create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.base.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x121.provider.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x121.xea.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x121.xmcycle.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x5.provider.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xaccount.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xalert.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xdata-collector.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xea.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xhelper.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xhttp.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xmd5.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xprovider.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xtrade.class.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Experts/x-test.x121ea.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Experts/x-test.x5121ea.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xama.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xcc.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xche.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xchlh.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xchma.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xct.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xdon.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xfi.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xhk.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xhull.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xich.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xlh.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xmc.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xmrb.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xobd.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xosc.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xpv.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xrsi.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xsslc.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xstr.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xtd.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xtm.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xts.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xzg.helper.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xama.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xcc.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xche.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xchlh.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xchma.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xct.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xdon.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xfi.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xhk.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xhull.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xich.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xlh.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xmc.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xmrb.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xobd.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xosc.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xpv.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xrsi.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xsslc.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xstr.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xtd.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xtm.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xts.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xzg.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Libraries/x-saherelm.common.lib.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Libraries/x-saherelm.draw.lib.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030306 copy/Libraries/x-saherelm.xtrade.lib.ex5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.base.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.provider.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xea.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xmcycle.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xaccount.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xalert.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xdata-collector.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xea.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhelper.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhttp.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xmd5.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xprovider.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xtrade.class.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Experts/x-test.x121ea.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xama.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xcc.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xche.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchlh.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchma.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xct.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xdon.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xfi.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhk.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhull.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xich.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xlh.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmc.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmrb.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xobd.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xosc.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xpv.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xrsi.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xsslc.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xstr.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtd.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtm.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xts.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xzg.helper.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xama.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xcc.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xche.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchlh.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchma.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xct.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xdon.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.osc.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhk.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhull.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xich.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xlh.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmc.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmrb.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xobd.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xosc.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xpv.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xrsi.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xsslc.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xstr.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.osc.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtm.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xts.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xzg.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/JsModules/x-color.tools.js create mode 100644 MQLTestWorkspace/BKPS/14030309/JsModules/x-file.tools.js create mode 100644 MQLTestWorkspace/BKPS/14030309/JsModules/x-shell.tools.js create mode 100644 MQLTestWorkspace/BKPS/14030309/JsModules/x-type-detector.tools.js create mode 100644 MQLTestWorkspace/BKPS/14030309/JsModules/x-value.tools.js create mode 100644 MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.common.lib.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.draw.lib.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.xtrade.lib.mq5 create mode 100644 MQLTestWorkspace/BKPS/14030309/compile.js create mode 100644 MQLTestWorkspace/BKPS/14030309/pack.js create mode 100644 MQLTestWorkspace/BKPS/14030309/package.json create mode 100644 MQLTestWorkspace/BKPS/SingallingXTDNew.mq5 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.base.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.base.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..cf13f1c4807e56311bd458025ee27e85254e94e6 GIT binary patch literal 5488 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 Ham)H&LZzpz literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x121.xea.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x121.xea.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..24dd196b867cf6ca1d98e0d8bb2cafb507e9a88a GIT binary patch literal 11604 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 E1&Rkoxc~qF literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x121.xmcycle.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x121.xmcycle.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..228b0398b5d5971d869d7d20ac8b3032d41b82ab GIT binary patch literal 9632 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 ANdN!< literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x5.provider.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.x5.provider.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..74c2d6dca009d322e7f7c0c07a555bdd18938ef4 GIT binary patch literal 9852 zcmdUTV{j!vx9y2JnQ&s;wryu}VrOF8woh!^wmGpev27=l(0dw<{BwR`Vg zySuAa?>}8FuE7rB04PEhf&}~n7~tT);(zl04XqiGxX!;?>0CT7o()=7ssGLYU*rEd z#~lU$_>ccjfM;!TT!s@fb6`u93<8R{Lx`;4-orLobW1yUG$6Aeu_KPbStF|c`p;fb zfE~ad-~n(1SOClb<^X2^5r752^v_uVbpLWyfZ;#Z^j}>ZU=6VO$4CRz{*9vlINN`# z|5N$@8UIo2{O<;w06YN3f9CdI#_(_c-?~lzOE<&6`}zM{>Hpj%W&p##ZZrMQ#s3HP zR*cz6N~KjLjr0e^wb&OKJNB+JiisVripZe}3#69cDj#qqhrqj(cQdE>3G(2EU+U(E zK3FK~U8*Gf&vNUTZvv z1=;ZFqQZG8(+n>g1huUpEw)MHlQsAKprqZ0vDCFVZp>PvRP^a)NY& zV>u(7A<}nxUXv&W9IF}TX+>2<6Txgm&t%eZaDC&4MajHVVx!_4Hj|_yOu4we8*%|d zyn7Fk#q403!8~z_=lN?#d6MVJRz%1xrqu%+(!;KYlUij8Gk&W0(y3^#!Tw%8B9?1qf? z%SVf>V;@=(I~(h?X`JpFUXB(oXkHR7qHy&I?-PYjk9-5AORoZ6%}4&MNJ&PKARIxj z9h;HufUMp>(99i~i`js2Ge2yIK3Am;!5M43g$E`^no&0h`mZ39Ghlw2|O`E6)-G;OrFQI@QwpUVg^Mmz z5<(!YW2p<^o35fV%00}=OD^faRr*mTL!^?8rkcR!jIkv$^;U9{yK;S!;hQ3lR{Iuu zMQz(4L(@A;f>CdS&98+rggL^oF~%2HacN2ktPD3n^8(i49)V|YrB?Rlj6q2528^h>e2P)) zh1@awy5y@9rOtHElTeLyTv}~`f_v;!+!s_T?Q?gk+05T-dyGMA`P1C%jZfkysM0@I zq8qSqEUy&rg$wiX?V%2tDj7K0RCVZPJ1NB695=A88N&${<&Q2v_~=1t1i{|-(yYHCb>SGgmeJ z0xB0|6gBE8QZ&F6=O@!eoP^;z^!gmD8#%Ia#2*b$Rq8gW%OJce95rt6fE}n+gMSO^ zYYzXG)0_?(W`*^*Ofs9`IDgXfw@zF4bm&w?;wwj|dRx%%MRU=3|AV7J_pP7eX{~ho zuhQy%4F6KS+A?#64&_FI9U=iJT&7ayuCrlzxB@|`!MWI=cmpm?gi2#;lz#(%mB?(DF*76}O1hw7D$>T!cvN=cj2BlTj@T z3-Hh*$54ggrrh(3J3ljmBoxs_v249-Sz@pNSdTp=TbvNr>{OJfT1kRg2w}liO`}ns zuVM*&Oh@`rI09L6sDtQ-FT8?BS}S7uQGdO@iZup`h+~; zRW65qp`PGnz#kw6VlQc{<`%*8UX{gQmXw0NgXT(j*etu+-n)PFnQAxV(MlQdu|)fv zup%IH!nOVteGuvJ)2odR=5>W=>`Pd5Z#SM@&N+|aV|!kLV{bg5?qMGCmDh3x-wVH^ z|EB1g-^DcowEl$DOZ~RU9gm5sS7EFxIb7P;*(C_o0!&yYbi2qVj$=pn$uh?>k(X7g zAEog{`MTILJq;NbztsM^9bdu~$95p$8yk@m=0_r$iCFdLMKG;7qO@$Dt|2k5thkKF5es0i=4bw-Xnyp8v|$87uHD})IT~hC6x+3b)7khEFRlWz2SG~(@ztUe@-pwMv_@7Sksb_$KOZH|5jb?S*$^P2LZ_5(+=-uHc^qXc-=b8kc@II%Ae zKRsQ*-@Czifd9x@=q&Ug?00F*xHYikSQvY5Ah=Y)QX)GQ;)RXD{Q~q_D2k#{k^VNw z_FCLboPi5p>OWwe3GS6R+|?O>yz<6b3%{0{Es^`v;2<-}xOLWPuSazR#Gh^{CEHV^ zbtV>U`$EgHnd6+Vc!x@*pjTozM{b+z|GG_WF`+LU*P%xhV;8BTniAG00e7#Ohupa$HmeFql_rjY_r-%shndJ8i{wfpsXUT3um?CyEj6gw$3$Q+r-04T+MI z;1Ub}_@Hp?1oMHxd^)3qICIFzE-96vHpz4XBogtCTE*?WY_U<+se}kN!?vYqlwRhR zs+;=5wdzwkE~u$KN|3fFwe`Yum}obKkrRlfXv!eEd9|JHvWtB>N6rXJ3O*i@05W6X z8Rt^AXrpT!U%Sy1uTdUWnNsm#o0U2r+tU356VK;44n?6gp@r znPA)hsFWI1EP7)2;FBjC>5UlU;uzaMR-5HBp_tX3;!LU%AMNYC7Fm~K3&D22K?%~g zi!#^0r8U0OXj3v#!r;y2pRCelQDp@NoO| z8(8O`!tXD}(Pc_~yv}GuZ$9QTU*yT#&S4+sHcefv%^=X2hqtBv(&&BLo~|cJ2enlp zV(Dr9gi2<`j4>t^?Rl&#`beG>vHz^uK#>!B@lF$j?g?$&#Gf6va$%#RFU9o#W~g&% zkGxM@qX#Ri|FU_3$N>m(b+mKoCZeP=?xz`K<8}KO@XKDW3h*y4l`M^=AD~S(=nCPl z8-hVHI`NXieQYR!&;Vx)c7;$hj#@B#lAK}yRp>M7bCJVIE#7VzO@6gFLiSUA`FZ_# zzldP{rn4;KJ}>^NFFXqdKo>NCmQOx3P~V{+z8pLo4kK|mL%c9MQXF(avv)ABSbuI(cd(iP<}94~|oKf{OCTH$JVA*U^q zdggl?wb8ExlCKn;QW}O~kV|f}L0%3$qQIq}<@hYLeLYoKTb>>%KvCA#sA`8%fOredR)MM1^pd<& zW9xpZlu%lmfV6;ceT()dhRdhf8TkXfKyMbVdGtADzv#bG_uWvAK|~>*gHmJajV`Uv zMrA{;#sc5dQpIfd?y}RIhm|J`qwCeo03~2ntuVkFeOE+fH!tvmuw*X@je9V4@u_Dv zOSf_tNBm6YJEb)`nz}c=^dsV(%ijY_4HBvQUT;+V4a#r4%FUn5KdZDB&2IYaZ(6+3 zt`2s5WfNs~Z{u+%CoMH_Y8wmU7U!8$VY2-RB@y>Sz2US$X{*{YM9m9v@$apqd3V~H zYESRn7`|l%FA|xJ2}cbgTm;41NuEi!jnmkW6fgXC%v$j_gDn6xZ|J~0i@;d<0KwJQbr)iHUG_|W$*gZBLY9|q4nxu7rb~ZYW53EKT40^y5*WbGBR)GcTKu|*h9K> zWEu#(4dAlU3|AyD>JM?F9f)WkMcNh^5Rqlly^8%euy0(24p7lU{}(wJKDy_A>n+dt z0pQN@Zid|Eyk9LXIrh*W05!l#nE;Q!K&vE{2nqIy;E)@@l(_*e-##h~#*DG_n^aC> z2E1NyD0qyon~aao_3Fw<$yi4Xe4cJ(sTuUym7D@qWGw1E3Hg2RX~4Y(&!yONXjx~p z5JC4z`S-^|BqO>FoUvEVWZ}WM)*9C>CUR|C(yyW}8Ul#>cN_mwfn7P07O4?U+Lccm zrYtV;2G8yQJhVVpE^RxA0c+77I-l>aD8_uaGZC(AAl@~$-=;&-`0w77-Z(^XO|DcA zm`J<=d}g%wWBs^M5cL<~V3R7x*a zE=z)Jh?!QYIw`^3>(;_7(?FkIVSkqe7dTf@b6@i6KK(Ed%P6GLHq0NYm&^oGOuUoF zVNnFguI@xX7uZxsne#2V`0bePfSSh!R=U#h+DH!meK(lZT3U@Z-DQo@Y$A=*x@551U(Ay)H?1V_AnZxpstk+2L09Oa>r@{v*l`%Qim7IF^m?D@eYT7Aq*_v<)GKoO=QXW4%c2ApuLoyk2As`@>I&O;%{ z@kW!Tm|>FX6273$zM1ROR`5d{&H=veI8{H@s>SX{{vDzyT>FL)xx&w1U{GIPAnJ_@_`FYNT9lk%A|OZGHQAnA3!)czy9zvAg$VGdY=OUnWna}0_<{|ovya8C9 z_rk?%hAFm^f-gcWskAMrXN=U2;NZAuN4(vy&(Xjd4tk$70|dI`%n{l)#Kzq(tW@ES z83eYXuU|5{`bJIUCe3D{$%35=68NX82%;TkaYpsRiWSnuGf++n!n;JNiR&;K3_kea z%YX0Ba_hS5QMaXoA6WkIQlE6>Q<}LFQ|No5etIUv>Il*}j=0ikdO2gSP2#~o@8D(8 zg1Y%FT`KEuJF_rQz3B$#RNg!JCjmI0be@Z&Syss~KovoiRV$1AeY92KK6CD7^i-Zj z5@+7Z3RU&#!iaQ7DA^G2>cTwp6J`~eCAi5o8#<3>o>qkA1Uy#3I$b+0te+X|NTdEG z_Lt^vo!wOyF7D)CEV^{cInq7}iz6CQ74&!^JV*64u)^MCq^&yVxCB2GEt?Blt1HU|2?v7=ADD5si>T;JyIHwbJLgAl3^!9p_y zfGKCdFLLu%G7ZAIeynX$OmoE(nmk1|dS=Piui`fOWM1mj20WebUZJy)Ky5$ih$OLM zs3!0ywUdB!h3GJ`e8un{%iO2P?jhb--2?7F$>5R5+ydY>nA)i9(O6j9mNHMK)wx$P z%yDd24Fj)f)>r4J1|H>)vqlK53P}{V#Gp^UFDR|1oL?a!t*5!!HTEIcj>?wf0le3Xtd03xTC70zT6H{wz;tMqgT|h(*^(^YONN3@ly9mv2vR?F_D~%@}Xhw*-&a)freqA206FqbU>-$I=U?$;W2{ zy9-)-$69n5#d%(_kpch1sP zl2IEI>X!H@@p{bOl)ouRlE2`rA-r30yjJYzsMmm%FE{BLxGq;e(x};2D1Rd& zeIUkcNDt(gJ9)Hl6!u3oM4YookERzgSp}Po0}&WC^|%koRXWL6!ChV0%tQvL^fH*S99)b|UYqC@l2oXkTk0dURQaCEbm3=A3wadck!uq& zR@#F*w=>l_X8b`lW~yx1jk}aH#%jyZmpgdEk*@$WKfDs}S8Bs%iXKC2M^H7R_Xiqg zdXQ30QnH!w@@x}|$|;geEnjktl2vTEZVQCKwY<_;t3e&?I!R}2?EYiT#M<%%3&lYX zw@z9wQEv&0N>kl*fIWLB6aeAh2Z_JWAwgl61Nm%X7M0&w?90;a3|azuj*#!CV}2ph zu`v%h*kWEm2KkcRPAFG4BFbN6&4PGQDCFpKgjR`5KS&2a%yzU4_;l8h9RinW8FZ)@E!?noO2~fY1TsF!DuQ{`!dIiGlU{#iwU#_}7mP^bK{w0QH9{5NgOq;?DcC;3C@JtAk# zv)?uP`a)uOLvGHr67hOtr18D5=5M6hlJ_ECWTjSk6ZA>o7IQ86jiBXLtS z!x5v4eJMr$U}FCP4_BWII|q5dSs&@~MwH+ajQEQ(>d5oTV?!{f5r)bYf3Rp+`HYd2 zy|^ekt&Jdgy9ZTBSiOC>!>4zzlOVig{l=Jz8M`7hM|!+nz$0m*_a}m(40YGp78l{k z=+*ID*F?mP=41vU{-dPd{D{^s1{Tw}!z>SoK*iE_bZWED;90Nm(OxIKLcC_E+d4OP z@uz&1loX4YsBLurns1{3#Y(5%x{NeMX|hmIU9IHaN9}%+V`#@HUuvxC%MTxxEylvP z!D?Y*#Xd6>Sk`Pz9an%`@d-`pyXvQtOZ7J{q+GU5TlVKb#0e!k!ti94pX24@duFpm z_R$gcqGyq|r*g()X@*2qvyI3wwd!@pxB}E!lV8AJd6hS1210k{uzSuHqQqnUZW2Q= zJ+C&7_uz9ga^DwwB$5Xga`ynyA`fX?t$J?cOKL5(BC{2tawqLB4&%DFqH1dg zcB7Aq4ub5)X$~j~n2GrrGor2sBwUXC?wucCiFUZ{KT62a zLdIjVecXeaOS_G0nHAO1#a`8-)5DnJ2{`uQWyCu?28+Q{b`^kj0 zMAI&6vBXeK^jo%h83SA+9v!jvR1BGS+z#3i7sJxY_~kbA1ENw~n`))%H24LIYK2AC zu(&HX^NoJUUHVAds$3H&^GCj zU#1OF!U*ahnvc$jED|T{5>ne$knxID0ttq!>avoL3AC)mX|Zp6C$C_mb#4!{3;)e_@|VAiXjo#aXhy3e%_- z%~y0t!CCsHzK?}I62gBW5x)-K_UwNr#M@s(7`5DK{NlV39s^EH%Ya?rot7q|7qpYu zg|fZ0+5r!i*XWii}{tt8Zd^HV|L4wl}CTz*x3Uchj7v(<9a?zn}R$fE*?cR zjGTieO8G`D+@#BUe+r;~MjwiH6F_c-xmB=wps20f$>dZcor*tE71$xz8s%7^&YYB} zX%j3lj_n>&jliKgv_vet)BnWB*K(q8&Sm*fd{dtC(K~0s57tMi4n(DCKigBW=BoiK zoUgc!Lx|}}^vJERL`m9ItDNYMc$B)>v{7y7Y`0m*Q!FULGs1wEEl6hMy1Tt2b!M2d zm;RgEtVa8?$qfU{c)`T<(RjPFz*}7J5g(Ro{q(fAOQ*mU31=^lbbz{IlkLcY`yKQ- z9Pm6#8!RA;Bfns^-?rmFKYu@9n((*4z;K0v#?RkuaFK=(_u{kK%w9#GDzaY#zp_g` zAnhfbyBHcW{z<@NQ6_GBzl~Ro^0`-`QC6e2LKaSZ21Ude=s0Di@{N`^rBG@KTld zl*a@E01qkM_k*7T)XRo{@eDPt``~`q*C}RQQK{gFXTm$2wm{2cANVwn0ACduXU_u&EJHVJ6xt7#wiqR_dGFhyT7(Ed^bq})+(%*&bc}wv^(soj2;8m6RWJwSw+BTi- zzn$5e%CYG{a#R{){@ay-dHmPR&3UYI@w50P!)Dfyc8CpE*aFQ(>^i`8S5 z+Apx=UBdv!qGF^He(0R>-vqCyXN&On@@D-%Rg0@X;xK!yXVob(nA7fN_q7Z`i za^uhfZoySlcoMb3u}4PBGxUZ}m_&21(tZi}BaWS1G>DB9cNzSL zYAW*UjLAA7ix@633`0WekU8(f*U*lDKpVJ3EC*8fk^)$Nj85?#7YEPp@R4Y62qz=x zG&;GYSy(_zc|594)_js^3jzD*xaqcUJ|4{97R$d@z^i%WIV;48g=yfkVS6?gM{jQ<*v~~w4YAT6l{9I;26tnj`H@dyr>aayhJf6Gi34x)cLAo2H8_c0_wD`gt@W^_wD?gS0s901G{C=X>;LNib^yR?V;ou`*vkJCF`Wjz zaG&|V@&C4ZfB=Ah;y;-pd=Kr&c*zUZsm$HX>p;CtA;we4epm03^wGzKV285LaueT% zSk3I8w~_#RfCIo2-~_M)m;)>TE&w_JFM#`R@Bujfp49+Ge^JxFycEC&VEY%51Hk`g z$-kK0-`oE%|DWw2#V&s*;0%BPxc<8PzZ~+n|F>?_f9Zz&ozMSorT=+LJOIewZFB!; z^1nb4Kyfj9ybFnX79dMA83v5VV1qhYUQnT$_sws!=~H)GOfdNxN~HRtH=eWsaEvt_ zb*ykg@{+n_Qc&~J^oRZsy}c-zqj{g{lPyV6SD$L^oFQV5-B+e?J`=;)kjb=uNQOzX z2IUF+y`GD+pnuDp%_rYlxy@LIfUu#Jwe-bBL1K2-uL9vIv_4&doSFVmCBn@uwEVj$ zFZ4EcySlLT6)GdPri9+aBWQA%Sa4n`W_^V72PKhD0cI8XmAk=|9LpwsTdvYB#xN-= zhF4xnFLP97?0a9?={8BXY8$)wTD1uh6H@Vi#<6o(8m+0IL zvu(!r{ntDyN9xjObp#5(Qi>LfuFh5d%%3b_#xNWI1&?i?BGz&ND+~Ida^C1*<{cX6 zSvo{io&u3^l;F8m2jT2TlTJz6piC=P~;7 zbwWb}%=NuJm}Hhty%l-|c@v+dtL7;KK&eC8HTYz|YEm0e8nDbN&!Hs{bnt6m!=B|o zg5k}|ZS=e$ggkR^RB5$@l(@dRwbtT{zSKd58nAhKMJ%MD!OAe4MB)lUS=@zGuw!T& z%|pvq&nf0Ahj8UBkZ;Bf|Ad2tZ=@#K96i2{yQ1Jomty_c>B!*cG446Su%LKxj4mO- z3e79zZ-t-T7JGe$@8lM`zd%n_neIq1B1-hj&uUMntpKCUOBoiBseGrys_~hcpD;@_ zZ8uL-P6jI%Fhudp4-zKP3O5m9~pVUXQOcg@*x@EB!)lLF;H58RBHmlwLI42baak(EX~Soa95g~ zJO^a%FYr$`^Y@&d#41+Ag^4VxkS2yqp~gn2+ZwPeU=G;A?X4~A^T*`eao=i75OYvZ zhq-!>M>`7ok%c}c^)PbiwQ>W-d&JHcKLhFMa;=M7soz3y<8nTtxQu-Fz1o9Qnft|c z@(v}3G3?(L>s$GE3md6rhPXFUpbXYh^+ z-I&C$DCtS;M%{RBlhfei+S9dA^uu(mIEb%aE_U_AC+iVKnZCM-is#lwCtv8<@M?jF z> zG=}8{fJC{eSe_?s2-PB?K2lX8uO?@-e~Z>pB)^YiOF$nO3+p1;C~;iK;wu`!LqwHa zmOOmO-(|~YxWRq}jmJbB1kKEj@oWd?!C*crs%%Tj{y-i#x8J=1bWCEVno6rI0^gH5 zDUC%`-HbYT^_1WkN-sgMBcoWBdZwTO6LTEl_7vLv)EY@PhVcD)BGq{Entc<9$YEE8 zS_Wcb8e$C@=Ky0C^Sc>l^*?K@T_BIlzk+9NFs4!=(IGZUeFrCa?g!UG5wd{sA5Bq5 z`zUW;cRg3K-MakaCE_gN&OS&68r*R-uoV6_zN>Y`a~OvVxIOk2D3#rIj(tm<84pTTNJ4@6q(lvz)Z zvalZ|si|$sT$MD}uK+2+Su$rS1(Bk*`SU7>%R3@u#icz zO$ECqXv83|;bwF?7az*y0ahnlgLpL3Imp5F+Ix&MZ1Kqpp@Mf2#v}s z?C@hg-#2Ix8Df8s&9yZ(Tu93mP<1zLGh~ktYKd=})H%8K+J4;oqqShS5mv7hHuzp|G|u*tJPyq4VKS}VZr>p- zs$#`VEv-E45EI-)Mnx7H?tXVfrsB0IY`t1cYFICP&e_V58e zCmK{Ay|%cg;}k2C4Iul?-|e#M+8r1sg!Q>grBUHnN6h}`6f9u%#P)~$7){zzSqo9m zQJ_oM`nIjdmQk&2xIR@2Br5fX?;Gttae+dHD_5^%9@#8b&KaA$R=dr?6Db>LugJor z$3^P}+GA5$ERuUs+Bx$udjucJ9C`8BelzCX4!o`l&>i#N>R(3tSSWt5JdlxUdFq7`cXwj!f2X9!B?{72?V$^u zmG?N`+>A_U+jZwKdEt43ZZ?h=03(f8@NhrzEpw6x`CO_OKMJ@!nxFjYuNowEC9Nnd zno!1UMvPj6vp-AFED#Yh-NPKrW1gfj{Z*ft|LsT`li@FpBe~BHy6?RuGDRxpG36&4T)$0T7V;9~VnWxp$A;u4A51|y zgzvf4rdfVnYG>kFSjR}daZIfznv$YjBS5e0HuqIB@QA0Fm9Mg63dVKupK>4)&`tCG zVwWKm;@;{pjI=$YF0YtC!Jam-Sn;sxk1v60<0=x{6(5bL+hxT`Rmv}LV5=$?f#mhl^>`2la_NNZJy+c znI<$qYf1}3ozNvCbBDxLUY<{9_^k50E=N%C_RtSWm2a?Z`d!>t z+a;r)YL-*kC1nW_i`(op5RaeUqUW9QceXnrYoYT~a*ci0%o1c?CDO7csPPl9Rxz~~ zr^IpORi1;;_70?7T=nB)?^@Iut~OD8@~m9<%R8v-D@{(!YDn8lKPinanVbh&gM1N%53wWWjM+6S7-b z*^OAHh%-e*%sb$SNk54E{Isrf5BueTbL{rw>c@8>w^NNJ@q*U&#Kf7t=Q&d{yV*U7 z3dWg?TL&_-WMxxvPg?+J|0yv?#;VWTcJ1w{meLX_nnJ9&G}i7#N%e%vo7JY;>%CEB z*V*#PQRQlpW$AY&W(o6Z?WG0}dJe-*IQwnx^Lzp?^?po6l7w{x5zpc&3L8IpIyjj{^pgoTXbEQ#BnanaZ3QVCDzXZUv&II7 zIr~^TcLg@vvE4mtdjwFIp>I>vlJfTQINhW-Q@TN+Cto?cTdkb+m%7U5#1*}dE`E5` zUkf9f|A=E(DQ=>nr#{VR#7@qvXIG=Ko*z$?93s|#micrvz4v&l?;uCqvt)L!t^UL4 zVucGuEvf&C!?CU=r5D%WTmd2V4c0!E{%e84eIWCIo%YSa##fAx)qtY4B8)UISD}SZ zWsHsz2CGA5I#+L#*KLYmfg%s^@;NuSxJCrQ>ySfs+>q}Tqs$y4=CY<{Yt;cIPnx|Dov*h9Er@AMwR7s7%7ifQt`KYCx$Xv)ComGqwr=e!ZS9vZ%H8_KSr~i z6WUjZS3g6BaM~pqQ3_@R(|6!k?XE!^8R}d944k{ zBQ$mc{{9e?G8Ma)UHhe6ed6o)PmPYgL4psdOA)s1DWtL*#AFf|_jqWy`aUo==b0|}%!B9);d!JN!a9tv*P6JIWj4I#}*jH8>$LY`1$ebyI8`3bs1gYJw4y zj-FrcLg|9(v-ZELK zO;hF~&b_7B5wLRzW$`B65)}=E72rj5D$veYu%Ut}1V$ZSM4+iHAZD5A37Lx&^yIPd zNqie1){n~RJ@+-)=BIb83zNEqQqQZ_PG0hAeoRPI#wdLjRQi4D{bHfD^0w+hsfAo= zu! zQD44*kAUI0qQjR_X}Y7wL7yK0yp~}T!GnaO)7?{&@J8cqyz8hBHWpJG)8H8@Bfs_c z61nlex#kcJ<~-{=IXo4SB^$nNjUT!-GT9gDN~t3J92yRxPE2aIm8TsMee9Fk6RGul z5Jf{Lm2>05h2o87ZwjL=DY?$BCN>3*G=7m|7a~;qDop#(o@(?PPt}uWNGGp#(f1Vf z{BtKsrW?haQN&mGPlkvgi}Mfm7wMhEI#x9{F$ha+Ck6UK=5< z&l>iTkY^ltTFT1 zmp6Hz+6oxr-r%F>OtBfh=d7#6o*OYx3U?xZKHtF>K&aBeje|ccveZw%Ri4>5^|7Tm zj=E1G+8Exc2JPH^JU36)S__8Dv;Seg^amDls(`w;yM6Fkx`k>dEY~R9zsjzKLEg$~ zXbdLtfcqbWXPz#m5nE?_85YCK*JeS3#-#u+`_idyd2^Eja z?yFk8D&g_XiR9EB6L>M4J~O1tJ&*}cDWf+|BF$BG(ydAr7;WNq$qP~$9f0IYsW7|@ zUr5O^5o|e%PCS1<>G0!4YfNo*Lf+-UVqTPRB#eaU*n|hXta%)5etWa#)>||j^cq;e z{DR0bZxoKT|H53;V8S-2d^w-ut?%duzg-rV+mHT%QDR3Dx0DZlxvl!HP5BYQEbBj) zIa{!M=1R;BA;GPKqvgW&v46NX7nB(r;gLUbT$*D?Nl{Zb?bk3M$2=VTw`G~x*=?+W zwL-MVoNs^%cY{BLz)LH`(;LdanQ9LGyFQJuIyct3=@6CbOZ@b_{9)~%jlh0Mx_UzWs@V``+gB3RzsC|LYf9oao@XwriJNs{ zLI#kDBG|cMFqCLs-9phZa?J2aq$j!r(ow+hp1TSk@36m**}%Xa)4a4 zB?Vu1a%RiBr#+SnEvpbDfyVI+QVc1TcgVi_&dl~3NS23IrzJuxrn`d(<^}S*VUGrY z$VGvft{PFYlo41=5Ot+tv8=GWOAv1LXAe*>rLw+Jk-gsONIjUuBXFONHuxuyDTcJ~7uOhS85 zkWWTx`@wwu9^=n|GK^vT>^Z;ZtTk^c)>=#+i^Lz+*akTaF7sF(;83O;fNurx@(bmM z+{tR}E*Ca8Y-Umi`tn;&j?VH7QJYs-4`c~{_&N+;?nO0z>H(xN#s=GtN@1t}eAcc< zaA_1Qcb+N=kwUYAyv)6x*4FH7%WOLV8+C*uzu-3d*vKY=SwV&duafGB7e6U1+2c(N z`>ZXBt-eBydh0*HA@~X;&_A#`8sZ*a*BhYTpx1b3sUsx0IDU#|RL_YWae07vXYFG_ zB(a_7h+@Q)GW>f;0tRfMKOwQl7Lgo3wW{p3NZ}1ins_p-uJcI|t?}E)MY?;2lp^AR}HgCi&5e(wCLYM3(JiG(c$=GvlSv(omjf6=^53aa=Wn2{AwjCIdmJ|e~yE|tG`G56)I{;v%@iSTh859m9rqQDX_1XWM z|8J`w1_1C+{wEYD;L$+1#I+9q*E*;sNzcx#TFi4XkyHZ8RE`AdgwjsNK_bq?+IIi^ zl>xW`+yVXoPkhJekW>$W6?NNqT9)BcVajY5qHWwx;HJ`e}z?pReval`Mf2DZB%0 ze*|q(EF3|)Pf?5t@^EXCFSU+!izAf1edj%I)bkP_!HqflD#E|;vUznNDS~6DKLxvt zHROGqa}Jxo*OjFjei{=*fsm#pl$uLGQ=Ufle02Qh_m|axJi7-z9`VFzoLcKlYYM$Z z4iLGKNdq&2CITd>XA9yo*I?;HO%*^h8Wv_0gW+3fRf>(%MRGxnEJ%h-P3+duEg`-p zodM6Df?Hoqsz_(@?rll)IL;2{akAv3=?{XVO!51ePDD^fs*xLIyw(KCT2oxuPXkY4Nvmk56gw8@sIm=@3DOAYN)bliqQ3xb?toEo7ST#pSpMC#;T_6f=O*iq%!U__qeS@EiZMj#b{o|Lek>OW zj@>zxtJ&zw>p@>*;2~c+kzj7KLu#4VV{#^~w-Twp+avo4C*J2~c)E9xbVYhPJ!CEN zshA8n58ORQwsy?xjG-RYK%9GLKZC`eQxPMdflZ94TLVL^n;D*_1;`gW zsNL))8T6jswQ?~1y#LmD`{E&7U0hL-bb($FI8(D-Pcvmdt+?JOZt7)46lt;{8=pJq z-J%l|)W)4#9C+uEBw}N8)FbbzV66Q3Xtc2Co>QUuXCt!NAaO>>?9YcWAt`1FDk?=t zcRpi3>wyV94N+>x$jm0$<}mED1tXt-3I?hasir@`b{wdVI(NozN36b9Qal`RTBq$?fiY&|WT5%<#y;%#%Pp?WpC{IM%QC z#uS8Mb_sS7$EUfCMUHd^$EZZr%%NN4T1LHpzKWUr!1FHf%Xa7@ZH*`T)h={qDwu)O z#z;T)xSJhD62;!X7A$-)$JX%X@DmmiKRCpftG0C!^=e6OT(xeSRy!ILketVDB}87; z+ZEQaB)S zu^>C zjzWhhHKAVw(WkESDqRl42VQE9(v);D?5it$*!!T7Z}{l6FRs@RQ?BIhAazFSM14TIL zTqjjy7Zmi9);u$vdK50YQMfc-hJtgm`_QOys<#V*DHu_Hat-a~-IS9+N8<1%w!4)j zg6s6sM&XD0EY3F_ue6h9=uJns6A`x2!k(iLgQuVm!FhPm+<2@Tv}^rbEE$-$B0EnIt1)@od~1QhmySW z`Y^>Q+ZNnlwBqeND(tHWv+p3sM96PLlnH4XMlZBulD#lp9o!VK*pdP50DF9< z7~Ot+-Jf4T@HWIzEh7r)}e#O?GB(;6hR5RLT4q zx7#*}^FU?A0b6#1I_q5iv7NPSaFvTb9$kFKn!WlXpp_EGc>W!2zI?bJnC$cOlLY02lsomS(>s0C5} zS!;*8GEkakp0(P}$->o0Wsshe4vO)NvVWmO)Z{~8uUI7fNWz`mR*WRI%Xecd+Hb0> zLZZ6#<7*beX}tJ9uctZpOZ2k+In1w7-!+l(+BplzdVgD)C3@TYE?o-UOF3bi-IDsKk-G>)m#?yr5I`lc|>S|x*2 z_i=RD^Xm22vsL`rm$2hkN)&N6&f1|N%Q&G)IE)s7CvI<(!3=iP zA|qMEC9dybBXR)~pKvQKI~Xw^&g$1CgiOJR;pa$>(btDGg0?t4YLh4BEPdY|X%5gw zjU!_lwN=zX?jZ?hxV^twT!!)0FkGtE!U>rpfjH%7+67D>6&{r-=+cld6`WG~K9d2I z>)D|;Lqa7^FdkaseMewh~TZj8$nShnrX^l@hogQHp5+d0xeuo-AmV7qHXqVAx$4N(l zrL2^mvC`SJZrPPm(1J%fu0Pg6y(JZNDY0y=={Y~It47GiswY4SAz>Kl>vWi1m~0-R z5X`tgTWK{ECWXl$kvd@2+|2RUygriT3Y$B{QSfV={laq0WL2uJ2j1+4u@D@kn^i`A zZa#UKE~qCeV>ovju<_y)bQL$4VrORlT-)o_bb1SVw^`KMeyoyVl9}~dT3t|O2Yk&b zL|GmbA?v!Wwn8oGb~s$AEuvV=kDP>Sp%;uqoQ*WO+S^gg3RS^>VX3b+_g{({HB~Kd z?>XVDyDX;@a)v8C9W%ICRrmE`)cfRG%LDxE-lxC){vsJa3#(6GL`(%m&R z3M18N_t!Qqm%yWmA+$s_`XzS5XgmlRk57^AP`rL3cAjVR_iL_`>~fh(4k%Kn4Kr=? zZvW81?P~+){YjR;yHjNXyGW)dL*#bmSUT9Nl%;Day>KnE@YY@oo?+U?ix}-@uwW3s z_35u{!nBqgjbUEjHKh$`PkE3a3E2q>Z2Ra)A*MQ_p?t3OddIRv?i<~H*R(4@LubqE zcSKk%ey`p!i<{+Z;-l!McK}TJoR2jmjO0mTUjYVoHa~wvP9^C zMBbnp?T3HlIxE0W)P=>R*6a)7<*k_NX3*JIcg~B*yH4(mYN?-It-+h7pKYFb^JRYv zh}~Zx4!$F1j4d%Yc;zatHc&lMquS)BGrZT%)baC;k%mJccr|6918aKlo)}N!_Y{u& zts`pdIgwdnGYi;cRGeWxAHu)FJL^tV9W~k}N#C*+=)lK|(37V<>9slDtYr{q(74d% z3B?H7&wyFm8{yx2*2-qCwa!*c1*-)%GK>1+vE;v!H+Px9gW$?oz0-W;Q2kYn=^D>Ya5YpBwqUlm)S9TCEuGCD$l-ESkRsE z2#pEBOV&k0))VkakZ_4JZIP+Ob)GOn%T-x3hi~GSm>|A|zjE2`@WeEa*0(j%yG(eG0t&e&qgl)0nRLiAvfw3PB0&u{g`xbi8mHWS1riLJ7kqt&31 zI>SHyllQAK`OKB0tadNrW?~$laZ&tw!S)ggWdQ z#NMqrg#v$hUbyQI!!|_=(BJEn>qNO(66OYZtre}`NhOTXgd^dcjmOPW+Zicab*|1R z_&W^QY|AY|(W@{5MJ2l|sZ8wzY-x<{5aHJE?N8G(VhqH$SsRxkP4iwmKG81NTEoo0 zfr`EEIe%6RB@9EW^cS`xDe-JfxZL`;`-79J@Np($zQWykV}{o4DcQ-X1H&}sig!Z6 z=S6-6TPM%EJ!;eLky@(*p2@BxyV#2uCE@pXxRY9|3yllJGw1)b6<%31&DfWi z?v5*QVkdX$2XcEhba;d>xtS=7V{Wvm1h)@YNBVWGDkwYFg%VlR^A(k|Fwz`f4;YJm zVYTqtAm4|h7^i<=(?O+2`{ZU>iSB@CH!sdaxoc0m5T3)?cuN82Cyl;qLzD|(M#!+N z6ps;qBWxUa4S_oLd=%=|M!8cQ<{owQ|5X@N&k*>g>TA9d-Wu8XrU8HqJvZTg7Fz~l zip>KA{pL#2ZhpeVb>|;KjmIQ2ttwdfRupr7Y*9K=HkigyC-OY-`p)f-oT;60Qt_bo z&oZ5K$u(S_I^VSf17J?f%KL_#vZo$pSGaJhWwEC?y`&CRv024ts;sOD-nB^kX18aT zJsX`Tswqd7GDq0chhlXdofF+9*+2rkGN>7)k=PWBrEzV^mIzl`$Ef<1{nEyP$J)e* z5&@0)WkoU-drRDqe?4e2mvW#1%3xCl{Jsq>ZO%g21FL*+umx)?=Cof)(dLQ#D#r8xW=IX6XXxY}GMg?vYkGNm z!1uMz)MJ0T{M~!=XM6hhQx%@6!4W4aV-(mYdjV z(mv`jxCUEcX4;CcFdVL_eq01(F2={rXuXMs6uo)>(76%w%@}wF7d;Fy7kO=ESX+wILL@>9l%r{?DkSzsL&aqo#tY+lN|-t71+dn1jTaxbo1vl=Iv zd0|tdH*{?nAceoDTdxYv;OzVaxQg&4!61szw2BKD9`IE&1z&WZPF$TTKG`^xl+FOL z2uaXPf;NAf5~;yLpa(N3k)mP-R^!b%yIuXh(TWp}>v06BrBJbB*zHlKv3+|S>X#_py}EF;?--`RO)2ghJ*Yhthd z*q1$0sC|i2=e{2ucKRqNI0X_J*kx=iChfk|ACisP$0cnDI}K>wt3dVC{3awkXTrmS II@Ig;Kl*#4JOBUy literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xdata-collector.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xdata-collector.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..8a48e44dd165710dd84e01b2c2a3fb8b39f7b935 GIT binary patch literal 5682 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 COtKvS literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xea.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xea.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..22b45a44a264a7567a374b6571c5af83aff4b145 GIT binary patch literal 11836 zcmdURQ*YN+qUi8`Om%Q?L3^Qx01C;))g8w+1f2aRb`TrUJQS9`u z1C9Vr0Np=x{V${axBqY5#{Z?8_FsSg|5o}xPl*9Q`)}Ix|8wzw!S<-y2w#cNa5@@+ z2mw2Ox)8#9xj0kZfup-gZ=@=oEjw@HLR!qcm6IA5+xw-Af%o@s#NQrm-lwqk|to>O54>@Pm|L4pjm z{b&D!eh7Pky9w%qf&m#X%op+2BL0*0mK5ZD*&zTK&{nK-mIjN&m!12w`AqA-IRL3z5O9WBVJx0^_0!&TPzSEm11EM1v>HLAz;@iH%>J3I0H<56DV>#M<}ftq+qqTRzER2m!i zN5JJuD-k;2S}S7hCv6s?UCc1q(={o+b8K*b_-%admGYRWvT=Bf)<$MGMYVG-3Hidb z;1zE6WiJ-qH;O~8yd5Drq20xYz|#^G?#idTrZ6=}*=t$DfhXd8Z0eYlLWa^u*ag%* zknkB*DfTwOp>K;Nd`!uITDfeKHu#bdRwJs=sB)B13L?irh%QwQ&v?!?AbA`v^5zjX zR{A@-HIO*qI}10ZhzaHZxTYjbiad7N8ri#Kt%@9Uf zswSMoy`KbSV8ScL_uRE+H+Q;~ZerA)XAXQ(J8Zv(d0`!`gHlSj2bcrATK~=2!jep< zS?v8YdrccU z@HPkjx-Ok1bR0hs0fh?Z7=*WVQov1LYNh;?G$P3)j51g;dP8aE)Wj(mqVh-Tx$dWI zrIUFO<_WnXbguPKz$dB5bmVAUj>%3KQbVla^1r?J9Z-Lrw*z4Z>&nR-jA#An@w&o;^3M7F?*pFp!?Q^U1aPTLzpubfc#Qsx3 z$5VNRN_mm{h@MCN=@Ja%e72lZ<4>q{L2GsXk1f}ohC{wp#y3;xM*Eu<`gC4mRy2?! z8NsRM!q-v^IB?IhW7)*_-g9l)+I+6Qng5><@+|fnZ9YGrpN0)#^2T!ZDe7`MZFow; zPJ@-U`qa=x<>J;#AMew~PbOa<+2Hd*JDOREyoKY9Hn(mUMOx=&`SFoRL9U7}RvtOU z2~LJ*B>WTCI^2~iIM1=ADurFRPMdtx(l>eY*sMn;pE)CEa?Z}8=gO4ei`R3NR?IQy z{Ctdf-e!FFtO{o%89W~YW``E;^{Vxu1LNtc8HFNS+#X}Iz)M51 z`uM|$^%M({EvW_@hnBH$Dk3vhVMAT|bRYH0G$usQQR$o=HXj+v55nBk6q^Dsubh)+ zH&mOxXyC-R*m;ZmmO}9)KOHIOa*vR8?d{`J^uoec97bAfNKxx7un?9c2H_$??&+lI z1;%`}urfHvSqiBsmqgDVR>SKUxegn8N(Dp5#UfM0O)q@0V?w||2uHUC6mjySNAF#> zwzDY$vik~eiK~lc4f>z%zV{RxYVj76guM?YFuyl2-guX(T! z6n;x=6C>intB_C~j^0P;8zqMD1(Hnq5b?30VY@%{CO&)~yCQSwlI|PZ)juPNOT~(- zBOR0{*Y!SZX&Q`_M;Sw!U9$NGA-4 z0wTdctdcI?f8cbz4H^4Lt3nSC<9cXLg#K=N2k%liGFCCnss>vM1d{{g>;Cl1t zzHzPrWy-)HFV*Vi&Qv)~4&#(_g_5w3tJ8!uirG-!Y_shi{d`>nanxvst@Jv!+T!V% z*JM4?36D0JFsJQPX<~-oaGaJjQFix={Dk`i8??=1D-T16gju<}(;>vh34550iSql> zJ9!V2GQyXO3(r_7_d)pG6Dm6hl9bDUA@CJ`PKSTUBpItoPC}=;Y*Q=4(w-LzAnFQ; zbhJHa71?x@NK`Fl|M1xTg*LeQfs3fi-fm}XS+}+Z6p2x{rIC1{B{tpig$lGXHwR-X z;L=$v+q2c2@B|FYDvZZ&wZn&l;C;E?W;ADr`zQ1xwYChzSu!0wzh}Wb>?Q~iBW4_W z$y6+U+%8=8n!%2*aJQl{?)EeP>0!qaZv^|LPcHXbIB>K=fdVp<7SToWI}=<<)GNkR z_rckzWCgO6Zoa#NBFcZWb5E_v4bGD+cWJ;F2L92qxl(*(%*u~;u@00xOJON16(L}Y zt0_0{dNY1{%NuJLiRPMHkK^wtw--NjrNAyD-h@a^cfutx!IBFzdDlyg=I8~A2x_Xw zYE>T6E}RZR8Vvmx%Gh1ljHkD1i(L~z1#TJRGAh3SCb}do)3*~}gCFLmiF+tqr)2cD zohqxo_Bm;N|B1z}wnv7*loXzbMh-~0O<0p#LQ}8fFLc5NI8N%b{92owz>-1iH2&J< z`DT7)piXX+1Qo1S)?Afvkk^S(@91ye9Ij}!G|v=w^s*Z&)9eG7t?_<&i!M~ZZ*4+3 z)f22Ms`cH!ONCLu6}Pxak?R@ZVvk%w!Iq~OzD)(W6M@juTTjL*29-ngN2O_v0b|7@ zE@Tt%4HWfzgEpWk9m~0jEcVv;N=*YH6+`IVbK3Y*+(Z$Rog)y7JX1B`r(Li^9w-{B z2u8Di4%C*^RP0d(-ucPb$>Xpo#E_|E=puj@BZ@La<%b-J^vWBqV#G@O%JSc#OWwcF z490nXiFh!yI?~aiYn+8692JBofGQSIO!7wXU)zsVs~Njdve4%1UVo2}wkX%UxK#H37||!&?awsVuZ++Km2q4}+vRZkbNst6sYtAv}H@~hW1i<3Gy>hzwUHNG% zDp8HntaYJNeA{<pYdiX{iv?tHVIsEn}Wa9_zkI|ydUPj3*e>6D!7pxgt^ zPGfB_A+X|W3oxF55{dQ$3@@!VALd|c)VXLv?X;0=|Yl8G- zOigR?DH>Z@eRnOo!oK-cG;1X-k3m)S-f{%ZZIYel|N69U5;US502I5(+hh1!tOG2! zsm~D{erxK%k6aJMI*B39zarA1=4gz1NHzp!>o$>zl?zw1cR!rM(HsPdya`Udzw7zU zj-9j;J2Y2!aJaI>@;xWY`8BH3B%VM?ewmE#qswI$DBhyF-Oh89l*4xpOV7mYDiBf| zxdTo<{PZuY@XX`!e16SgpH#DAp@5NFt~rODp2DO-_H`l7hvV-yaMTK*E$8Ft12QK+xKWRPey4UI^33@!u#VBHu{O?uMePn96+?c2?u@!^dJ`f$MBp`>@*W6c=9zLaGMy z@oj9R0QeNYJpJFIz~G_^=g4%GNUI_&>g0Lz2ncQwFI2}UttC(Qf829-dfanN~aueHNw3w7= zeYrk*et;N&h)PJzo<_4GoOt4zFD<0XjU< z^il=`86iK4mQXAMH5D`xrylr7p5FaQy!wRx15~FU;mzeLzqCF`UdPU`U~5djG@Na8+Z@5XwELNemnEEwnUL`0i`tO9HaJQXai6Wv>x zG7Y62BnllnEX^rAMtZrylq>T=1k7cAk<@DdWJ=SMQ5FU}@M26=ZHuw%WC7DHd%(CE z8H%tp*6;`-&yXT|sF~THk$MqHd^+JjH-V@6@Or>%M7}^IB=<(zFID$mpR&$$*KX(} z##_P!XGVbvV(X-1L6iH`y9@M&uIPyLO{8FxDO$=%I>`ua3FtZVqAKZMhUmUSC;dr( z2xvw_S$VZ~LE1RAhzKnWJD$s%{BS*j`CqKhe|2>%6j8+F1pk!jz-Kb#@sd{N3OU*p z!@}Y3ms#3^RUhYm;7EpX$Y;ASuck~SM|#ZNaU63*{hfPldN2S@&`0o#eayLSW(C}= zMS2W>;ksLpl5WIoC`Isi?3#P%Y8WOzqSiCnVyY{PV5G=*L_d^{E&eUHHNJYRC~B9a zGhpJ>Pms+-!=qy?$3k3kOU*56O#N+CO=FJaFzLShr;$|E}vTx4qGm7YgZFAgGMz309lLtfM`OMji`> zqtZwoapG%$fU`S8=(YT(Dz)eO{?G)V8{%4*x47@5Ws`i}bR{ik%o`ZOgAkl1w zI#nqT`xi4?4L;iX6Yzv)5}=V16>*ePA04G{7j)$&HP6tsPK|9fMleqSccqg|73=CW z-;lZBjAkpmxtXe1ahx%_t|#1W=xr&4xKEc&WAX1nappYEybGQf!G5ORQGKq4bv`Zo zRWc?Q&Muq_uFl>Vi=*(l4eLW%q!t7!nIia`dK4xMv4CYely@pmLe5`zvy9iccckv6 zkM7!>bQUr);RHP*77p=aRhYeNpb}kt4ES3dJ#A=9yiBKC2kaghx;GDE_gB`39i`!j zk&G1da;#|*vwaf=@6Xyyqpn?jXmSL_@t1&Khq8m~5S3L>>S{@P=do>E-yyTsE{CBS z%Suswo0~xrBsV>MmTv_G%hLrY3``yq%91^lUp37d1K;(dGu0TxxY?B|$BCglV zL@K*&p*~~)*J{KKYgL468ofFWg?9QLEANE{JZ@AS5e4NO;(HOGjyve_F~-&!d{}># zmr>tBITqIn2pA1vEtV8)1sEKgu@ZotjLKHgfPr-yT|9;WDA^e0m`&MvfA6P^lZDt# zLk*Pk^B;>^z&{12Z--?5D7lX<+!B2ihX$~rVHyd5FY~SJ7}pN<8WG& zYT5cj&=5{cS4a{(X2!ksF~9QY7RrDiMi%cjNEe8prC4$N7#X>}u`1BT;Z6K$aR9pQNlE9Kb9kJwZKxRT>sS~1ESQztSD#y?xZd_qz)Py*a} z#6ls2t)ac?F1f#`Q!w<}-yo^61jK2GGaW4ws=6!;`ubvX<%osP=W?!Nga@<<9iR_%21!6S#7j8HrOoz7KI^g< zT7)^yJ99=?+-u!Cgw*;9Og%M!r8sM~dV3<#M)mAStF1`$KgfIgOqx;=Sre25IJF&x z{nE+F?U$o~3UkUQC+CjTk@`zocMDQ~#gmV1Ry%~5dpn;0cSuNpg0E2TQ2=^m;(^&&}l}NRhBwD@J(?kHzl}kTHlVuZCIrV@=Q5_F2p z>HBN@W~V_hQCUTR{bk96%<=Ld8rp-Ce-N&(%6axAx0hd)6&j%eZ|Q zotr(9b^wf8Uv=0q3}@*xdUFcarvZjdGlR|fj>WDqvd8rl#3^1#g5MxQtxQy}xohij zx--v}wF~44{LL|3|3W5O1Wi_F>;xvxFO6V=vR!tAZ!?)_@;h7da%Xw+Z)IBmvQ&$M zSX!T-!h%3i9Ha|pKqlhZ_Lv`qeLK|dQc1diH2NpAzhf7J=$fB9eAfXQM*Vq;pT_av zK#WMW#i5Ev`pm9j0vCY$UO_``?Pm<8%G8c*>)?n$K4LOaT-4mD2^}1D6T0X@!adWm zrOBywgYl0nnzvsd3Tqoyd0pVwI#{l5gR&C%$KP=JY(TqrbJvszUb`r6AYi~TBBj`?A%GUB=f$=|hNfE&mW zo`$CE8<8dvDXmia_P4F*b_Y)}nizMH4>oI75i4o^Pj% z8P~g&s@%jG1R({BOkMBVlT@=6xmU8mL>KSrg2q%PuZZMx=p||%b#eu}j2gEC+!KxX^wh#svn!WW$X=QgmdgX%nL+m z2&AO?{+#KJ5{oJmz`vHK9ihbU+EYblgo%K~ObvUwE03&$`aZ>ndwr@kw+6WY_7S?? z-aI=Uu=C3QH1A%Wf}i7EKjF$Gk7sTQ9KU-W`e`ESNE2uJzPEqSo7Wj`6gGioUafic zmHVC&I)mnuVk)Rtt$E_$1#2FP(V>4$g{1f4FS2*^7M`G42c2)aEREwp5xz}YoaGNk zNO7kr-#+^+7Zo=Zr|(#7e?rMxGb}W1Iv`WB#lf11F{LOe4R}^EVV!1hHmL#qVR2Hc zVlV%qI`pj#0jbVxUQruiNVD*q&k8f*P16pn^)3PriX|oqK6f~mlZ5gYm)vGCSEd?2 zc9rQ6|7d|bqBd)*RCD8;ra~BE#GhE)8?b|jsV|=;k*^Tpdf4A0wI#OOMZDv38lo^P z0`#ruMU;haa-Bktd+=pX>$|26z&%+ z6fL&!p26df5}*76*;X(PT7!uEE4voxEOUyl5xg$9jG7n4QMcLTnxu`;s|meGsFz{@ zet28NbXi0Q1%tSA?yEivFs>N9Nv!u=NM%c<16%iV2e`6w-S@x z?`$55^;WY%0@6?cV1h3aFj?%660m0ZIx*$4ds=qeR{f};wX0BaNgzUOCv!y&e;B; z5sfHaq?s2g=osU{x)=e&oz8Sk5+Tmbw0XofuMh(cz(NR;~ z1e@~W+$rs)l6#t9AOcQ`mgN7|yd@T^Un%FScPOO3)ci;bL9)aw$@7r?v}Pt>kzT@^ z9NvNs>rfACC?Z9Cb^V3%4#AB`$$A~+8ikSPWN``6mUlJ<1$PP<_Iq*GSK z6X@#%^&_|vd%y6PiZw&Frt;hcmzT+$dewpVF#fmpUqeh4=UO*ybA`mLyj|j?HA#?Q zLii@-+Aj4PLodm*&txaCie`rUwgR7Lg5CJ$%JcfT3AjMZ%OrrRUj^o@e*q!3x@E?9hS(G$844403S1^vQw@bY7<&*`A?Y8-tmANbTH zoT{&zCMIUeRkfxZI{@_rIl9NZxRcTrn2YQlk*6{(i1T$b@Fo@oZz(@fAZBQr8{#J~SC>anXYKH>WHwe>iRvi> z=51rS3L^rH*cB@_i#YGh2srG+HRpG5wYza`6g+f}Qaa}=(NZkxWTDw7SvUp$B;jTY zfrKAW7OfE`^9GAT0&=NXOYdTRG>zs?9+wPQG3S?=mn;OY1mVBuj^Sz0+2UO*&*qsTlq7*K8~>41S@OS{n4mjlig^O`nZBE_!(DUSrVuw&y(|i zkdBkJ=Zpuc@c&fq<-bQ>eLIh~=2P{W{8mm<)No3Sn1^koof4_pM` zFg0@jT&A#jfI7^v+zX*Tm4UPfZBIS3bL0<;KUM zlcJD0W<$i%Z4vr?B6N~}M>6TzSEaw$>UK1f^Tl3M=N81)+s{|zKj%`Nz?(p9fJD#q z0QSj@Ax5FJeSx9gsq0@UyH%#QMPc|0whC|bBYPxQ`N>J^yf$8yuFX3v{y5ARiX!3Q z)gBuq{Yq4NS*yWKd(+qFeRT^noFn8Mdg8%aoW@HVxG+UB_|sdlIGN9H6;^uG;c3Qc zz?=&m2C0uvD9VF<+>F^J9`84%&hDmKeQv0Ta1Pa3E(hybb}K3x`3CO;l8>-52vHYA zPih%we?C+aIiV4YQrFokpzgM5c7qRF8?J-NNV)=(T5H=EVd64CQL&M3Jx*2NSH!i) zo2>q5AJzjLYu6^rB6UWC{r)wXIT;_^{UcL$`BE70EdpXU-}Nt)yC8LoTQh3L_lt2H*5G?!vzZ1lyz#2*sJIamu2^xA7ILx_u=RqEy+ zpI`I8OdPX^m;IvDv^XE4gKsAesYPR3_@LCVzpn0Rmv{$bd+7iI22AE@#ZECLkM(48 z#aWZM0?sfcF$JHN`QNx2KtZv`dr0fRiNjVPzv`Zj3)f)RNnO}uOO~8unY`V+oXP#R z2n0`Q$bTDsDAEQLXB+^BGE@PL?40Rs)CjyJ@OJGsu|DtnwvdUo2Kpi1@$1SUuor;g zi=I;Mr!Jx+f=jxNhy}q2_0OJ-s@4`CeIZ_f3g3;TL~ChzXkMfg>_5`+UkvZ{H1s7O zWceZdecMzw2SBfZ4^C*8tt>IMRx1#p2Y6Xy&B^)_+IQH7 zfq(jox8d?A8#{T1bU%@6AhD5vJLzY6|4QNnwh;oAKTMN3u<{v3CbuT7#FU)FZuE_M zEYm9CZxZL<2WOs-bfhM*d7)cOFS$r02|TE=nvL`I_&yzO_)?DuN+$Rs2H!C17D`I6pYC8R4wrQ}~7_3b7F3 z4YZ%4Q={*|z}QO)yvCVhkfTKVgudRYkrU+k&1iYUci#yA%QaxmCO-g@N=P?}x#{DD zDB|g~Gw%6~U}g76G+4yd6??Fb+U!R}1eelp{`Y4*bd!+t5NJ6Y7yBs^BoRcb4B34N zS8)|zp5bqTWqWX^4XX@IrBpOGJFo=2AX~)81^d@~z-2B$^GN<(xGe>kHHajy$9q17 z#Ubx#NVp=wbga;Q6b8DojB} zExb|2s>hmjl{&;#@H@MvJ}wz3gyS;F)k%=JJKNMwBx8G)Kg%5`NYz#G1UMdXdtquu zIxR6Qhtz#Bcp$vYw>j(ev+qJ;`He+ENEdl^V0@0Wzx>qp+0(B~c_X`{h!0oD<4}xf zxk{Ri{7k?^mBh$U2wb&Ny zy&#x~8LLDckG^K3o3;8^wQeE!{@uanuY4}6K}#%)I=AWY?1 zyVu<8j-aDg+oK+&-fV7gMkSCY&%I-P_{e{pSjq6s5EL5z#aFn0OuKg0AS&CHrON|)5+Nk_g73vX2rMd0^GN2*1 z&cxIm0)E|(|28A2Wx~nu=x-%ieCv?#@(7N+0Q1;*Z$?G=1QIT2QtX(xfs-?}sxOBo z@KH6w>j)(a>&{?osONhVo}|HAk@=kyP2$XV{1FBAt&045r%Wbj1Xaf3)X=-DOscJ9~?ry1hVFDXq2G4?kVIzE&(Rjw7F!!e6u$~Sb z0T}9Oc6F$a~D&)u_da$8ziRi+K{XNZWbR=dZI&c+%kY&kM1)ZCOv)<6# zz1M^Z*Drt2k*#TT%^jB!*Wo)QKYAm=BEOzs;E9l{eDwXb9Ra-Xt&V7gX7`vSu9e7? z2tT;szW*LGC{s5bu2kJe0Mb`7lfua0qzpvM?gy*hQS0@SA{1P38mx!Szhs8QpZ>Sy z7j_}n&hJy7TU4cEHl%egDGvA?NodUEz*>LxjbaFsP-~a<)^e4aOtAzf2cqzeu&R?i zQZmk2^N@wVO`PT6^7jxyE(j)BL~3JQd2zFLag&fRJFL zv=1mu5$r9}ja;V~UO(Fw7yx@PG=(p>8IRJrgRUI7(Z`P7)DqQo2Y+Ln`mFpwb`y_P zTHSj0ZoOH5b9kFW75bJ>oIlR7jWL-Yp`5bA`xWl&q*8h30CB2Oq+#c`LVn0yY%g5k zG<_Tfv&>k10;I5s%;5F0_vtLuzsjn!hVRW(au5ehVZkP^WEEzhoLsLE`wd|!v_ULu zoQ3>9ynK%Zg>(uJy;cktXjQjYzp&s04_gpIioIJo_RU#p QPYT*1J4}!7&q%@k4|dnZA^-pY literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xhelper.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xhelper.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..c20d2f1a8ba2166f47d9ab8d21fb22de530efcd1 GIT binary patch literal 6160 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xmd5.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xmd5.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..7eebf5240ba9f132cb2ddedb22cf23e975ce3e0f GIT binary patch literal 4348 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 Z5L;6%*6U=3A3+{lU?t-YpZ_pb@h=r{K4t&_ literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xprovider.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xprovider.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..5c85680b0d76466114086d80a2f068992cf54be3 GIT binary patch literal 11150 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 I(}~po1D6SC=Kufz literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xtrade.class.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Classes/x-saherelm.xtrade.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..3cd2f9c8388604301ff3e0d979c6c09280c52ed2 GIT binary patch literal 10990 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 Gvi}DQvKO)d literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Experts/x-test.x121ea.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Experts/x-test.x121ea.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..44d56c2fb81b030b3ecdf83f05923eaccb45beaf GIT binary patch literal 265056 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�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

jQkdBM_| z_HJuwj6(M-7s+-#^nGm8?&8^aMLc+Q%J@)&Sut3fHD-bffTtf5B5ggj1wLQbeO0n; z$j4t*Iu|X6t~L-0F+GS_A(`GYzQfe-wQH++d(rWVJY!?3Jmv$_j@uK6fymL;$AHFO zk(_tVx24;)6l!!M-HyiZ6F2m8ifiPB;|fZn6&+w18>%~b2cPxku{pS}>Pq1#bGWFE z##2Oe>XStK4v~-E_udKVStJ48#8h*^Taj1G1V!s^$`;vyBzB*bOY?D4&_w1?*9F;d zFXDV|y)HCE0g2jdLt7HDap7f3=;l0iDAQs2{gGG?S!#9XE{eEXX>dB}7m9@?@a=o* zI-SL*l3v+4T&zXg+Qayud)Q{vcLA6k0sX#!=G#j`eQM9oAAbMrPq1WH;=V*rjHygb z@|{$e;Jk{*rzJ+ux|Q46{UWm!(ux5!yRV(D|K;zuEEa0B=vSZE?AtppPjjw6b!NT9 z!f;BStJ``dKT`<`#X|}lT$eu8bFTJ>*p#V_XiXLUk=LdXII|*P4-+|t|1xokWInqt zkV&R&+$1Uf45ooph1~bn3?}o_l{*7|{QlV}T`0$F_-vz_h@~bmVN%s28k!O+0pz;e zmCBqPC}TVt=JmB*C%ik>pyh!XW}bL zBBQA>q!mn!R|a@x73A)2rLvB>Eu;%uc}Te+)^%6&bVYQRV1>!s%XWvS&snJSJD(`2 z^BAaa?cRmm!@JL$#`?n~<+S%VR02v=RRX1Fi*gNFN-<{(GTQ|Rd~fN%1Dxi}wfqwE zG}pRF*GvcUvgTYUI=5XgyS`lKqNGg!qVu@5@T~s43-P$@9@L6^GCRA2gJx^fi+H!% zamFb*Ug3!yM^CrAdgHS^zQLd=YIbe7vxqO5@qS4wA(nDfi!}3UIWET&8Md+(xjN)! zsCH^)eR7E6qP98St>r{_<_Nc=ma?lmV<}l- zvJe{`ttQ9M0hL28;|tF349~m6KL+BC)Xqp~;J44?9`L2A$}>P20k@3t2!S?{YxU=4 zF~T26(PJ$6=$@{vabnkB&z^ZkR|c)cwJ(s|kp{OXh^pLE4HYm*^ht+X^Zk~Amc^u0ouoI$pEcoG7f^&46 z;Fza{GR-_Nor*B`>UIl3Ln^%Q&bdKk5b{wr^*+W9!fTvil)W%Mrznc7CNi`(^N8$e zw>$Hr{X9$V2#^Vm)jaaQTAu1bH!7_1TA!|s!gzsjunVbV^nJ);aNn}<<<`Z~x;@<= z4|60BxJDc>dNF00Etvw&pVv&Ve&aS#Ozdw+bK-^l^>f37nyM_n^GpTL1ivgHu6jxS f&B|{dK1!baUCTiACbOFuNmE>%&J><0bbkFm{M}!} literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xcc.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xcc.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..e01067387dc864997a3a477f0a17768a0291abe6 GIT binary patch literal 5900 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xct.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xct.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..b08f82e079bfd57106f5d65c580b41589fe4f19a GIT binary patch literal 5510 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xdon.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xdon.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..48c1a582bc59541423067bfad213010bfd7e044c GIT binary patch literal 6180 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xfi.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xfi.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..4b2e67d6207314d4822a0ae5669b6716417d0049 GIT binary patch literal 5516 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xhk.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xhk.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..0eb02de280643b42c12609dcc92320c7ccc781a5 GIT binary patch literal 5592 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 Wuap_t8tq2XE5c_dG%YMkc=tb)cBZQU literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xhull.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xhull.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..bca8ad600dd2ff17e71ef0caad62dfbd7d82bbd3 GIT binary patch literal 6228 zcmdT`Wl$Wzl3rW_galb6xGwHau*HMByZhoE+}$C#LvRi5k`N#`ED$uf%M$c>@7`5i zUA?Nizt>$oJ@fUZkF8 z&j3Ts@*ig<08RjBfHwdFumM;BtO0HSasUT_?bSE|Os{h_fXORr@fw!|*aIA15m|ux z>nQPxIlk`xN96yr{DZOEYX)2a0sz)m_57!@ysrO?x5Ynsv%Kc#|2NZrUnO<`%WJjS z{(bQOfF@eLXU8S;AURNZG--h|wnh{bVs8Qsx~@>x0cD=2keCoBO-Mz2*uQTR& ze*>p*waC$#+I?V{-mGeWTDps&w@SO9`WCNB zxSedPAz&u)1nBW zTRT5^KdAYpW{zOgJ2HB(iY%y$Vq3A29>_N5>yIU%-k@sel);0@*Pwc=!^tWq+V>G% z_ykBM{mkg<{Mnw%tCTbh9IJXtdth-zFWkIjW20(Vd^&sNv%u@Egb9A-kf}=9C;hb;djHsW>W}#(9OT zcho5F6~OG=rSO~035&~PZX1;hA=*E_lH4ONH@cowLSt`lg=FG*KkpI#H1xs0ICze^ z{Fk}#Ll}6VXf|3e1Z-mVNe|WGJ?7zPMXWllePee@y4H$p>vu$=Bzgn(-k$Ydfg%TaR!NcGeJwsa6Pdw@)(Z4G zHsvyH46#gf9BCtc9FPn(E0q|Ga2+Yh(#1w`C7ZL(KNJFT-Z8#0izsjZypU|5ubcHt zAKk?%sKrFZGa1kwh2cfjC1F-^?+VdoS{eHLkFKs~JC$L9r)-goor|}D>=J9e+uy`z zr)hv17Tv(;$09!{(=e>Z@!CMpE;f@lbsWcTJZZDhOK8SlX=gO}eWuTe&Cw`dvM~-D z2Vmq~OH_fpdd+6%88(_(e&x&NXDX7FId*?Ih44=gxJcjKaTpHb>>89SuC8#*anXvh2tnZ?sMBi#$M)6EoyzV#5rx?%88OEp(E@jUyKTxn1uT}B zQ`-t6KI12e-sKQ9I>BV|!Ry}bwmF{o*k^3hS3i=VW zlqpk6SkSGaai5Rd|C^p@Wk;{s+w2N!;YR9Fuya8@*SLi&FASIMP4-jI7{}jt32>;a zvS*Ji7-nv9BmB!3`42rC*FlUZZeR5lesF^?q^M-;v@tCAD_K;+T2oK%UF5^s%L>1K zoTv}F>NFHbP2-OL)YdVK?+=G_z}Z#HC~Q_F`RV=(Hc`2ki#zQ({Z447u6DWFct=

CIVLdrGu@JZ#8Xs`F`LfWzpEKBChDht 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xich.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xich.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..6f32605cbf16cb058b9f0ce7209cb62a2757a43f GIT binary patch literal 5794 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 ZCelv6XTq|(OM8NCAS%7xJ*9l|{{v4vjFSKW literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xmc.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xmc.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..19a65d26be5b25d1d3b5e3c2a5c67d4d88cac198 GIT binary patch literal 6412 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 Ls`k#zM)Lmwe_+_i literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xosc.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xosc.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..106361b5aecef7f771eed41170235435035c3900 GIT binary patch literal 5902 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 TOX~=5#A8g|oiysi6pr^lbygbn literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xpv.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xpv.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..562979bb56491cc30bf506e1cd50c00acd31906f GIT binary patch literal 6872 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 EKcH{w>;M1& literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xrsi.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xrsi.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..a7d4c25297e53e29c59bdf1a84e4bf5309689a08 GIT binary patch literal 5720 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xsslc.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xsslc.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..ddea39b60ee31c9f711f3c33162039c5573b54f6 GIT binary patch literal 5366 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 AB>(^b literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xstr.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xstr.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..4505e4b2437f0cfca6b13d6a4a8488ea61b9e5eb GIT binary patch literal 5486 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 XwbBOJF{8+E1G(E(c-^hg>|pgj`IuGO literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xtd.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xtd.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..7b9275b1681a6bf6068a2c2acdb722b4355176cf GIT binary patch literal 5250 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xts.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xts.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..cd79eea96c1002f837daa08cfa833b5abcff91e5 GIT binary patch literal 5718 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xzg.helper.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Helpers/x-saherelm.xzg.helper.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..549d8032ff822a5c6eb674f844522a16106e6ea9 GIT binary patch literal 6336 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xama.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xama.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..fdd1ac39ac0e85eebc6c7dd1adc2d3b70a2cf587 GIT binary patch literal 13490 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 MOJJvxTt<8 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xcc.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xcc.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..ba23613f5c875c6a030217873b991709ff7508d8 GIT binary patch literal 11746 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 S<$mAPUn0q8A^IYRQvV+V7Q)y7 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xche.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xche.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..3eeb13e2a24de28d683b3b73b3419e73f6a4f7d8 GIT binary patch literal 17584 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xchma.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xchma.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..85f04e9af57ed071fd6f1349ca3b9d7e839b1193 GIT binary patch literal 48370 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xfi.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xfi.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..d37ea54cd30d9940d5e9f51be058255d32bc1e69 GIT binary patch literal 9800 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xhull.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xhull.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..881393bb269ce276eba6797e6b417284c0d16630 GIT binary patch literal 17748 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xtd.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xtd.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..16af4cac2a8b490fcaae35fef8cb40635bd86112 GIT binary patch literal 15400 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 E0@IOqNB{r; literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xtm.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xtm.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..daa1753e43ed554887b047bab631119dc7016041 GIT binary patch literal 13866 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xzg.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xzg.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..5077734d2a4984b2e110fc3fd1128fa69b98e830 GIT binary patch literal 12442 zcmdUVV~}St*XO@&+s3qQ+qP}nwrykDwr$&(wvB1;Jny1v_rv>rlS*=Pey4KpQBXIc z8myp>fD%LjPyitS00cM!1^i!WB0e=I({VmHcei8>LbNgR{{sJY$p2r$|L*^Q>js91QWv$1hZXk+?E-WVyWI>{d>NDhD$f+i^&f?G14P zy4Us9Y}Wq}RpOv#_Jp;7f#Pp>dAEkTAHu=P`N2k}5dQjgDg{_HLT`s!y-$vw9+&EY z?CfZG@b+06Su4lmQ zFi`eUd$!$a9-_9QWqxwazz_9Wa>s+XJd^c~NM#(IZDs&72mD7*JhWYlBbWZpj1-{; z($Dv=SGWK)4HgcH9j#c7#3A>I;Sse4Ww$k}2`&t?4h?gIw4`G)!Ic8CdL$SqVmXbO zP&gwk9Ef>^SiT~#>NZs>yD)?Fq4((^8)@%XH>xGD)$%I5e9{h)V&D=er%%lea=@Wo z33*X_&N%*uC}>;3)=D0uLQ6QJE0>%NV8VOn2Z)L!5QJ%~8{09{w(QPDoC;McR#>k# zp5jwkSU*AuyWr?4XY#$-b3yMghoV{-1G;b zC#4iJH%L)<^R^^=@zySp$T*Jd(q^8^<;q>Ds5VoRi4cXOl| z$PDV7IrMlEu61u+RPUrRPA(H2|!kRA+W~5aUVNDj>R);-xTq{#L_*afM5c;h~bef}9T# zpO>GyQ%Nx;>&%>Za>lkoz<%=GT=HnFozikvv~Oro}f&+_b6dT+E~u&dj0%lK-^__@=nGrDVo0rl4E#{SD+W<;wQ*h&89h& zcBzucEOKSwX0ej^emY14|860M6#2L!$~KtscUd<={v&sOROQdLk;XXu$I(%a_SbmP zhPqn2!5Yi*KJi}T z>u02D|15a5J8oP=T~&2~Cuma)_pTG!_T)vwzXY-xD0;#St?~5 zI(13+wPQ}li87Buzhhw!l&0(_DCF!f>RjW20#WYTO%BSW$c?ZiW_>Ihwga8+{+6@q z!j8@rYLc&Ch=Vqg*D#6+3Hup^OT+P^2J+PLhO}+3W;1Q$G~b`@39?eMQdP)MDZwAAgaDzra+W&%lV))rOZ**?$C$ws;7E@8XV(^8=7Pz{;MX7$Y|0|Kb6B zz#vYal~)M_aYrEa{}u!%N7hL{_z<{(%%3Bz7Fo1h$h#;XAKqw7KC|rcg}sb} zO<%FI3UoiI$Z4}DW>DL&qvpSUBW0>*1{TZOijCIk0aX2hEPCC>Vqn+JH+h;~PtkAY zK-cT4)=1)e_PZVA7^$wBNXSQV?=ShCSWmq+u{ha(l;$K@elu0Jls%)IKU{y9t!pOT}>k0`T`F$iBn_hZp3N*rh)pa;3j`7^=-Yj7B& zG(2@C1264aT-k)0F@naCVb{LcA`!5-|7Pg+N7y6eNdlQ|mf+0a-7sB3)ZpAiNV15^ z&&7q>AA*Bu7w}DIP=xs!k(A4K;Jj-?74CPnTeK8_t?yfvS_XVLv-8RlP|?m`{=_+u zTinEj?k?XVI&rdTkXovoFA^YQC|KH*azvL=M-)xr#@QkJ-#d%}m` z;BdeuX^*t0w2xj0a#0&4G!V`>dYj^aa+#gAR2h{wfz{r0_3X;mbWM`KK2u&1oIFc* z#bKaaf_C3RrtuRfWCRPkx*3$Aa;u~j?GpY+}e5O~qQF(+zMzi;L z)0~ShI<4YlY=?Zcxj8ty<#z2Zlm8hSyS$CN%~YlcNw0PEv1_GJz&TMro-ZNEbvWvV z^%j*5hpR3BMp1ra! zsZi*iMt$7Q6F0CVIH!4;q=5KKC)}GJXYVmx#n{Y_QpfuR0C7IAKOVtOl@$sAZ1fro zW=$X%wl2J98o+1jlULGYKg3#x@d!%Lc&0E;nhQR7k0bH8MU-9l?glUCAx<6+u9Xl= z2b@o&rFCmcE@o5ntM@0%ksxT3xduH{r0yyou|Ypi0@cL6XNm=44VJ54UC{Qk_s*t& zyluAJQw#{xFS1WAeO(B)7Yc3B_zC?@mzwW1yfv$Jv zEyT=mJ9MJ@cVzNs&Q&t&l+^+o64Hy0xItvn;Th^lJw%SJau}!(;uWv!D&|QhIAZsL znwT+SJ5rsHUx&P+6w9CFMu!&uW`^~~!EVHnGqIeSEjAWZx{P980&yfk8O$5)`x*Rq zWDx2^-sqHY_dL1&x!shPcbnTp(=-MnlKxnarwq5Q4Wv`DdxzI3Di`bg(-I$y7zDKq zBRwsJ^i=|!CzAoAGKJ*}KO-*62&8FZ1heGOwL6)L&VJNNtOV?Wfm9;t>1GdPO7HkY z4<~U^D+uZFU&*S1UZS(fT&1OqaJG6?M3zn3d{UkcLv+XTlZgw_9pTxjOHxwKOq9Mk zWO8O(>b=q!qm#?njf(t#_%g>`waS{-9=Jh?N95G5hH99F#xW_dg$dfC`GT^DBtA7> zl)~D%Z!&yQJ-{iD=oW!zHefcvCxORfU)}^1B5fT%ulD<=HRp#)!wSi{+hD<5^2hi; z$CMGVIRjW&IKWw9{w?fIIozQgR4qf*5xMi_A>?l?{2)>tMiM0!(CHB|C{nppxs|TX z8Eq@u-1;xQXQR4>xpN&nf{J_Vx)`5DH*}4=G+$Tu@7IH`jK5p*^e(*r-0k`jT}7ol zBJh91y%7vB+((G{3}2yRR{?Ruw9J71t=?QO18CaVKq-ztEW;O_U`dIF zqg&YBa@`Nn`GN+4iRwZ%oyIVLmw3M}lxa^*Zjp(Z_|(R7+ZFJwiFs)yA=QkA+zaZr z@(#cCf>Bj{Xrr#lPD)wPic@7YDYp}Ux zQ=)71(vd2%wrtzwJj&i&bWoJn%jI?qXhW+^tTH&3yI*_4SY0oY_lbXUtO|%lg-|4b zcM_H!|Cv`ue+3i{i-tNWRm_`v3XObtShk(p%Nnql|Hf3M8B#nMvqgd1+3+GS&dY?X z-G;k>rjWHZD^+F_G#tJp^&drrtu>{O>&5ckM&+vm~eEN1DXvR^8zN@el^wG`kDj%c}PBp zM%f;EVZ{DmeByqXxFUmPIw=}&p#?`-IY}hDWb=YYpvYQ+$xOT=Nl}J6M*K=<>($}P zi>nVpP;8$hEzv-NFHXV0~yjv}| z$aqxn#-f|hoQmD-7j?7&l8tU^0e;2DE8`&;_qcI;>Vj!pr=#{HJ=M=h&q21&mQ&~Q z3|??~LAT2%-mVCRKcz!8G{;Py%m^gNt{9&4$+5nL<;&O3D|p=**EFC1f^3Fflv-uX z8(%dms~BO~S*n{)58`t%p75RT#Znf1eP2eu5wpGG-p{;%tp1Q$uv@3HBb8M~4qo&q~ zg{O|cD4TW&+B;y9KLNuoiME<}O$rRrohv>`2QrZ29zazbeBQLXY)=Fe$I}-s?uZ~b zx~zv9Qi9J@ax&N#*O%wzpiibN7hrgT;?v(~&4ZOqq?*W$gntx5`pK5U?=Fs>ul*CgbyH5u)6Bz#BzIcuT^*6c0yZ!ja0CVA|7b+%lrB9xc{Eyo6PxWHf18G4Uy9A$B0y7 z`PGqBhZ=xh?Zfw4Sfqdo3ruY;N5*Jrp-(knKB8dXbdUHsYH}J-q$7l^E2WI?#ON(f zF+|dG4P1Z6&zlL*z&Ldr1VM}5sv+$15B-DV_E&3wtNfTS=@Bmx^)+4X;oeHtyg4v? z`sRAyh%=gD_F;;F-Z#eoZKV->E&SiU_5kR(tg;gmJ41B2b|=gT ztf=L^1SCE@AShy3e#(m5m_-1>Bqy?(wGY+y+TA`y4UjN-{^kYE?*3WE1ybI{PEW9O z7SvcvIA&Z}DsLF*;ZlFY^+NfT4BYA?G)mli0g?bzl8c8-o=qM^VW(oW#596 zSn3rcmLKi8U)c2AiY8%Jo(~+U(ZKm1s+zg$w(QQV3zM4U2Fo5NjM5L2VEkP3ZK=;{ z!j1)&R;I;Jyks0#Cmps!A+DLs7gl1p&|5Wt63Wp|Dw*fN2|g(ws)n!I+1NK3)b99-cy+<@udigPreGMmBcD z+3GnJ0^~Ac1Yz(7E@5)*@28({d?X9R^VE&~@J=$e116B+VBN5~!U_|i*9=y*xeeZ! zBXzho_Q1Om$TW+Ui2Kmh;{%y4!(nAjH%SQrzu&?$n|H^lC##QQIVI82qqViNfr>_j zqK_$|jZmSwtLMe|C2Tr-fl#_3$@M-5oCJ&l-W;%WF0i*(tj`jz)V)Vo32H%*c?}Z> zUby{Z3UB4OT;l%qpP@2$4b8v0_1b|_H743xxfwZ{)a?BZ)ud1HQoywm@ z3iW_rK@Xx&Iee@1Y`ed(<`<)`{u$mgINxD_Zg}hs1^`=i>wkl1BJT9e?hZC);*(G$B3h#c^8VeqG4qa zsvHtL?ajV*>SAEL5@4u@_f1Us|80H)&z)oTe@3~EXIlS>0`}r7>zwO>d8IoG8|)fj z6L49-RLQTVXNj*$q(o>pJR%7@Yk9GEGqBmC^uGUfX$DN=Y_COBIaJMJiLD_fn5oLS zqzF~WBRnvWrB=mPJfLRDd?~abi2qdAR4|E_^V;v%nNbk$a7qqMI0?D3DOilRIYZNn zyUl1?mqSX~vd$Sb`%M?naPmtlst;5`)v6t%X4F{~lvT^r^W13yFU?~a<4e)gCy_Qk z@zV0q&QeU~EJNOYq9uZ@F#xCA)W0u36jSjo(rLkFyfG;&X4VO+1K0ppY$RP{!aok8 z!u#RC=%Sky!ay@~0tg0ffa`@@Vh_nRNMp}((Bk%fcuD4TRQs<~8r~i{9zORwZ)ArC zMxj6wRm=1VnAwz2DpW+Up@hh8G%Z1%w|Zvu@!!2JTmy%_z64)uy(_T{JP+f?Fou0a zbM%TfJBG?IwMM6syu}1z7iL7njg1iS_dbZyWJ72KGDaL+ z#bU(bXv$A-a zsamiff_5`A~Oj$jcdR+T)J7rG(;i5aYM9eCs1?kWp1+^W=)s}QqDs^f zqXPZ5W_LC3*_ct!Xo}i*wH#70Ah#$|53dD{Dp(*%syVd9x0tLXs1?%C zOzkq3;!PjsxqnJ-abrUG#`^+IYdcV|OlMzQ6}nO}>gaK_jg^s}Ju%Piv9b5VJ%r}| z8iS$36}@8hd5g_pBa(Jz(b5x(a-&zKzB{rl7r3785_QaG{rR3!T~v0#lw<-9 z^BOd1ZHjMnF_cRDE<$g3a+U4QxR6xt^+NF3%ctPqydQOz*O7|{@tPvGaHDQ+mO$T_ z2chxinui}0#2{9x(8<>5ZM*{BIMoYNq3K(Wa93)J85QwuOEDvCLJ%>JrfLCo4q$O~ z;V%#oLKkFR-mvhKwzi5AjGFeD5kM|Q;Z1Xm98{2?ljC*)ks7a@-Tf7*E9oQ*h@V{W ztX>ez{oOdi+zPiMm}4;qn(X8b93eu_RCi+AFUEcro;WBEgpeM@uL*tqhP>D_yCqbp zjN=FVHmaV!U@#iSDZ6A-$`_CGi~>zTG& zNKa<4&Egt5+-;nRbZ3HOWNR43`;v%DlI==j{c{;1yZgV-$ z1VNjh1a^~#72m;_bif97KFqfW;yI&f^~_ah@cC}fS%*EzPkM$o&Id((t|-fpGEjrk z;-cF8nIvL1Lajj~@g?{3i}&X%dV=(y+3Va59A~eLJd58ZVG4wWqhAh@)+DPuu{qd# zg|e~DT=z3Y*9!Eod{Q(ex>C_Rs_#!pQ1JO6qWQtZKvFrAs^f*(f^?;CWKvdffNUXg zbEwc4oQYUrofa<+M9=%ZmX?~0afV8p=ckGxG10wp5a3qliT7z6Zdm)zt8Pi2*8oxP zNK@Jc4SYG~_6`e!T!;HbDaI`rvEG=2+S$S{QLmTg*NP1zy#U)73D$)PG2{;54EHu%1@8NGcONI@TDqN)nsgiTqqSb_D>(EouWr*G^E$-2IFcYHPd#fT&%>1 z{%+DZ;VB)~-^B~ZS1vcm0xEuPbv-iwc4@qc+j77E)VY99&BK(D!@-J^iqBy-omj0t z#5=oGRga&4LwGmz2s8-=#UV_@Ame%=7iQ#jA@X>JM$)vDYwM!KfH3ugVG17~om@Bp z9vi~i2coRirgJM~3&SK3$K8e8eU|I{#J;kD&(221I2XEP(CB4Q35%~vwsz+1>dX$B zj@&%wIM!S7DM_hsEu$YK-alVX}ma>7NVQTL@gZ_cHU4ksYKdue8sUFNnS_9^GmJ;|5 zQTGoeD%g|UN3$Z<8FKwpb@`YB8@qa|FJGX6?xo+zn8mVOeLZ%mI|(sA^$#xTiR5R+ zXpa0|K9TK7MF|w2mHg#hwLbGpR3r7dP7v24geeC})WR!y3jT2BThMKi~Oep02;d@%O@ThO0J@3ER|$SdujrnZNZ&#$gK zj?VVWCytEfAK3BE8Nh;?%Qv5n* znOK-M+$KvTFs7MNrPQ_^g~RXRxGh*D@*|36`HnnL*d*bjk4Hjb4Vw{f2%(=!7HRy{ zX&_fyi8i2`VS++4`o{PT<h1*ZvYeuCC`9TD+)2V~ z#=bEL37lh%XWzHD0C_$>7vipV+J6Y;q0(74*KC;WuvXxCzo3=OFC4e5T}XJSFKgR> z82My4tg(ke(=}&fv8|_up^7(>5BsTv>o!w}V_a8@BSja;@Xj9!4bwY(_ZVC0+Hg5D z%;r9bv9opvWq0W5AA$o5eO?86em@IL4_uPk^bN~+${n3|c(8+nIo*d}7g4n!fE#4L zMk$hFyPEHDH?Nt*CltGMa6(3;z;`2v+@1p^xx-=+i`(t&d~R(#JoW*1s3epjq$k+N z8$37r@n~G2jAQWIx^$Su#PkQ(e5dMkQ!0A3X{Q^>|A1*+ueT@SU?_A~`LRSdNb&KA z7`HW)J#ypfmK@^bx+vA<*$%Xy8q8WFKv>U7xZF`{u!!2k)w3HI2~Anv&xYDh?g`qx zO*(JU4y<;3oTry9J!^Kql?=^VR;PAUAY^{-^U0)81=q05=JyDzsTn{wVhXah6hosp zLE!hg*@X5zMfgd>R=3}p1i&)*d(P3QB##%i7tz4ksUphKf$ZOJB*TzOtY>Wr2UTDm zBo9ICB&QFS{UdtUkciR2`@OvTL5tp%i@=28e>XoQh|)bAO3Pcu9t`vdGYr-`Al?j1`?P^47Hz! z-NrGgsSJgQf9)>ZEpSX?$67D+o?K=uGG`g{G^gOH0fQ^1|E@ecLILVWIf^QPll`L* z@;6)&(r}G~;rProoT>0f^#|wD@|2dEN?pF|Z@ELuNB=ukWJjlpV>c6khdzIw+F+i| zBI(%*U^cptljkp(MX)BI6|C}dN=DET@zDAF+I(3Pb65JfD2!{9Q&6340w6ZA$bet)F_rYbK;6N zJuNicjYp_r##5DjpWT*)nYK+yp(4}$=F3nJR;OCx&Rg8KQce79p)U zNlN=e!N%p`QkLRlrc{Lzw7N4`%wZHhavX-A+%x&aCI^n5br*orv1bT(g*$-xSADRhm3i_<}o zf&FT)SDsSZale}wfgN`O1dy20(kkgn@@nUyn1x# zN8wH%J%myj28HH@Y$^ALHpF66idxtl`=4pCfQlo%6(6UN*i&Y$1%pabn}AVInTXs|V}O_M+}q zV)_1vCnxQN7`W3tar(zI;t?unJ|>johxBjDyo(Yh&<#sh{m1_`8rW`dSoP?a zhC#m4%`mMxXQn}ph9>{L|DbCZ)LFizXtGWx&3ZB0HXx9r-#;NdrF~}|+A`6h1UCf_LaIT6DtV>KVx{gv|1Kt~Ban}u}t>e0Y)(0*nYNqH4u zg$)HTXCllSqAn2GQOHr;b;JUIEp5dfmr!K7`{h!K%N)ZSiwv8O*S+8*_n6FzCZKI> z&a4iE#k^vS76vfR)6Qbx{~!Cab1c?DBRh)oRbO+Et#I3>zuSXZPpuXfhlu5q?}{5P z7GuMp!0p%ZCDackjQ!~k;k1+p)1P@{f@j2sydL>U|Bg0EcCI^HSn(gp%uPx7IKLJ^ zYMbHmf;UX9;n_}3hKdd@kwKd&Lj~0uw(Ho|`~7f_j~+JU#uq#hGkUBV`p^F(e`cUQ zZEF6G%;@u&4YJENq2QliPRE_btStcXAv_-v;XH`~UvkUIhM0;-10ENRdGte{=GjQ3 z8Me?a6!Bl}<=2sV1|CPL7Vc1ZRj&GPF27T#1#I-g&)pVjb%;*dMZ(R7W`xXdo+-2_ zl8E*mQN6{%m?9XVx=F1~vZgR{uSEUgfO=k+x_9o5+m_Nmax}Jyz68urnT>-~HiM(t z=F+m7-dorweh7eGl{?HK2zqc`>MkhjtWS4kWG;B5my1a0r_UA$wvX`}_5Vy6zdYs> zN*h}FJX!A$o1@>?$d`2|0o{w=!`<0kF*!Tsr-KPS_k4BxiJPu~f$Ik|YM4*zOoydx zO3C}Fi;9xEQcYSVM>jr&4XhxJT0CQw>q1hJMNo`z$0o*G{-J*Mtf8+w;nis+degM& z-PD=vF+y!D)Y8&Vv{J7oy;jy-2{ENj+F1H~6SQNU@*Lq$uygZ6WmW-Djf;DXqmJ;< zsyW!VnYx{HP>lwiVrHrb4Xws_&LU0VQWc4mQQ)GtV(oK{NGtpCo}R?%a=swVwfJJj zPR5;Q$Oy~QyCMYGwUf4NNhl7WgUY!#9V@Oh+CufDnaW#*xyrO*{gp78jMw4_KN<%) zj9qk#1o%dwo*hCHIOf4fWd?r-v-t+gx366qt{$zJ8U!Hp^HFrYC0G=ufQlxJux8J^ zY7J@j5m3MU-7pd2K=4lOjh__=48cd{jwNQD0>%Y>QfsvWCGI3}Y&@l|wmbSGDSyf@ zv6fFkGk3g(C#PrY`D(FGV1@EjspRR>vc=-M4}xWZRe*AROl+(A zD&WQcF^TS}R^CGv|IQv0fKUfEGCB9XHZoH3Tq$*d0>k72E~uIycIKK%xf4-d3Rx!F z1&4%iZdm2|Mq5W^*0ar4=(%ylr?oA`dyv9Jw7I#5bg@QLV!O1V3VK|Ftf}l_2dsOE z>I(UjuWRRDdGae@1s>iRz6$d1Casadm9)Lo-3m;IbW~gIT;KC@h}Oo?h0+Kj3GP(3 z-fnKKxa8sSP#XDjM1TxN$XcXa!=ctGY*=DFEkPz0gwQjSZ`)0NtH-luQ*;)hsqL$q zW$YblOzNf8;}2vME1R2Y;$FZwyAt*GAXlQ!%#e)k-%CaX#t7<_FX&KS1j-}|ltwy3 zyMz_EvIBXSjMuU2oyOCX+nSvixFn-R>PIOZ{9m>ndh@Y?0wVXzk=X#hKW@= zNRnw@ybE?@mH%?u^mh%a*xZL7CuljHQb0y+xy4aaBW@`M?fLI7%JeOvi>jszYzdHt;5_prMx^>+B+}Q zX_t@vZ~XuC|9ZzA0|5Ak{U>RJo7kIp(~(YjzVrt2$I>ncI;oFX!I0Z5R)O@w;vx`j zHVkzfb@PARg#qjV4ge2;6TlMi5nusu0nh@t036T84PbrVs{=kfqh`-}IKT#A`;5o} zG@e)3GiLXE`X8D9X88wWm*)yN1B3wV&x-h`LZ0J)^EUe@Z^(0f{=1p}=Pq#qAkW?A z_|M7z2fE2k!nY5;q5AU1A4!w`9+Q_9%(?+N;>9F^ahu1udKxkw*+u~-XS0eq$j-%< zO1AgYry_UVs!O_8^pWUcLoYYrE6zV!-*dxO$sVPf(j@giOsa`49PASlYoC2bduWKE z19Y=iEVV6&00xq^MF)_@=24xqZXSQ1TsmjnrIueEF;y6vsWOBj7LutcK7J~e+RN+y zWEk*0)e>{)Qbx&bYl|<9$xEf-22Xm#4Ve|18)_Lc6%f$k_aW~Dk-+sz6lZUlW6@Ji z%=v=HijYvD#yEs3E$DKdW%q2x zMYHHoTWytYfz~1BCK)~iNHF7Yr?H8jt6hy2HRYomFBvfF<$(lmu5DMBMU~wp_mO^+ofsgoadc2&8hq_av6W(z%8w7 zIAS490!a$@YuX7SA2Y!o8uvdi8Fgeacse*FXQ4otjZ$s0S)8`;c|+FDN^J`2DOn{2 z@}83MPcxy7kk{M=P(u7v)mK2GN|dz|^T_~VrSJg`r6_3nN~eNG^P;lC!kRlAu|_{Ey%-)kYd5s#66*iur`aty1TqLo zI}B-0L)#uPMCU#VA2y!A7_r(MlA#!)mEC0C7{@_`Ot|Y!(lAAQ17FR~3hfQ91biP$ zPLr`UoJ^fKqg08^ab`@BPTUgzVQKoYYZzM)MK)UbclGsC;G_A2b7-OqzNZCy?O)3q z&%ah8U(7^8Diwv&=kM)leboFX#%GjuRL0qVxxI4KxL7M`_ARrjFB3^v%`(-&29`7o z3hZft$*>O6@<(}u3S+Mr400!;Rxe97{S7RaSYWj3vNMzNQq&!l>RfQyWos=+YiVaJOA2rp;?U_Akop_U!NPP8mVc7k2|4NE} zj=9XY4Lh=jmQWa-V?W6;Uq4)g$@&AOxr1{SXCEBP?)}yIqVC_(OH~NXhyb3MH(&mE zs1(nHKnT4m9BSX^cf2AyHj1A_&BqOShu+qRUa_WErZP{QxKRFkKSR2Jqj;~wIQwI4 zM6q}WK?Jsm%qJJY{waFI?k4j^=ESg$Rpy{Pdj6~6Bng|jAK)Ji#Efa@6f*B+ixThU ziF8w#X=@i^QwXh7;dNS)y5Y1?l z6_9=18mytJN2926YTc{uXWHafFDf2|u;W5#u_idP58;^T*uprgK_0Q0%_dtHRf*ZI z#~kIW=~B-V!V^$_RS{e%+Q+n$JnmW8quP1@%Tz^R^AA5L4u#;Ge!!5->GU&9fyMy&uwrA zS8D61dJu+8sF&&TVAcw_SfV_y-}+0}g;Lod$Y#c|xku<5*Ewuite0kqTV<@458_ed z0FJ=AZ5F+#PIS5BA(UyJ`((Cgp#;OCR~4GbAUZ{ob;`@P1`ULG407pxETbm#7%BSV zi-%jpyka7DpCH(JYH43J!5PJLq{Xg33J_k-({GzVZIb>MG$av78+xayqu*8lPf-FL z_vY@rHq^R`?)ol39XA{{I4YL+Y01jgiWIFho-+#zH8CuuCI7!+P|t z$ImuwYhA@xy3P~DR6|W0-gyOBJARFi!D8`{+WwyNpjU{S&wnWhs{sWQj` z>WDsYMW(UG?X89mqgUUInZZvtSp>~SzN=F{67~5|v`8yfXjaJ{M5pIX!&PE+orqM? zj%n4EOx}9&Vtg71mbhYfsC$%f%0E9O3H;=qYE^>Vg)c7>Yd;tJmfUCXGh3}Tk!s!d zdr4mKB|2YFfwIZum+^Hbs4FPJ#7VaWAEo8JMTX>na`8~zXPPE4Qs_~a-Oap3V1nAT zCMDI;sn{~gcCdeO{k`0)?Rp$xotRT5vy{FO0m@%VXzqP@bOQALFgAzlxLT^%v~Mtu zz=ber)nus#78FlMncny1l%Fx?5Jd3}oK23GK2N z1w$paJkbC>)S!$u85DORfh9u`y1v9yHoC z7OWYcl7Wu5E^K;FyVx=Kdg@G8J=#5zabGae`+5j!z&tSra=1)EGFCgp<~t|~$rm({ zc9!GLh5Otu@p*q%o~X=-r|{ke$`q(vE`H3mRLKDmq2+vbYz{~pbZ`dfP@+$88wOcj za+VmgUo{D;{{dogXeNan>(7p$MF_{CGD z!+BZ*!t;r;5U;2wg*677nDi4BDk4sL!G$d`(&q657ekMxIx0>JGnrOKc)68#L5qv$ zn|xTsG-lKekgB8LGtI6rHxjqtxn0j5ry6U%$t#=IZnF81j^|$!d-g2H<@+>-vktqO zC}uM_N3K;X0(6)$pT@QGDc>PeOBOs0WD^D8A;9E&zxeLYi64+ zzylcPWt-4#Bzg2%I}I9c5wJe5$wB_p;|4a5rLDL+Dy<^=wU25AH0OQW(vZUx4OM;U zO7o?=+YP_#&0MJVNk6F+@jDZY;kJQNapE&A_OuGZek$@{1o~Ll5#BoW?wqecif2$Z zIJ_1o>MpB;QVCD#J(QOHFlMwOvl;A=>NT_JZlT8pF*{8zQYa}uzS#VAd?y*P_eQt( zi>)bgBx+?GT9N@j@q$FVvWmb9+eLNjymBw_>WC_R5QGk&`%0%q>yv*4nLFVPxne!j z{c_AMZ{ety^J|3)6@?`@v(n+!7X+$-d!yX&0@-lG29)=}djG8-j+#G}<;DJ#cnj5^ zQ)5yOamfMsp@n5jQoFcRu6H;`1dcug#>-#)z^k3*1Lma|xB@i(O=S%h7)CdWMTcf$b6@6T%`@Y z3QvnZv#{VkqMGe!3IH^|DJ*wb=b&`Zj;c*}gmKOaSnJVJi|atLjhIX{qLbJsOJsdH zD_@1vI~Ug{QO$*?zHBATE6k)ng2@r$BIsV!YD5`*#lOtX|ilg1xx)UqZJ#!^2uZnXWuqW1ovIDYDT|_J=fF zeS1Oh?H3i&Q*RQB30KWT2~=99k;LmZwR7>&t5UK4I*y~g3Zv}k^AHP#gw6ZmelE(B z9h}FT?M_Z|@Mz`Bw~4b3ILbO}iy55ydLgtT6YXu3&8+#?*U*zh_d@YL-f>A5c^_Yb z=j?pujVk-eQyieWS|JmXhs<19sxD{3Z;yHNaySro%kNWM*JE~V9!Tq4!fHJsXl}w_YudID8pu6KC^5I z4J7V*^OIZF8ad_Q(?LfLQ>>W%@62-uA%Bq=1A~=BIof`Yg_tb>C<+4B;*tPvDWs&Y%+!VF&-y;?DNSFR{YF(r1udo*BXZ zHH~=02_H)rbJ@_Z5JVuiUItn|q+8*j7uI zBzg1H=$WU@V`&{N-@K5=ulbK;qO}zwi0$<51jgRF(S*zomnx&j4r4C(bR^FIMjfdd z6ck?pMBvwoohIuTwnUEM>?Bklk9v&>u`$j6kxC<}6cdMvnAwWc3I+kAvl@tTlR4%tu)>)xTT% zh`Leajv5{Q5F$fWn>xdjG)ff|0OXLJfWDJQ~&qAD|D!~2;S*z?d8pnpUY8~)rJt!0_`Hx7hNKk!v JYw9u9{{YYutBC*r literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Libraries/x-saherelm.draw.lib.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Libraries/x-saherelm.draw.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..9759c154d9e18b1695f4c03e9916ff1f551e9e4a GIT binary patch literal 6092 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 F{{pJ5cxM0r literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Libraries/x-saherelm.xtrade.lib.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Libraries/x-saherelm.xtrade.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..8cbae8703b5116504527d76ead84d06127e239d6 GIT binary patch literal 8016 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

B-WHve=vXXwJKI6t#svUe5kSTbnc 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.base.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.base.class.mq5 new file mode 100644 index 0000000..cde0dd8 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.base.class.mq5 @@ -0,0 +1,88 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XBaseClass +// Description: provides all based classes for use ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// XBase Class ... +class XSCBase +{ + // + // Public ... +public: + // + // Protected ... + + // + // Represent Basic Unique Tag ... + virtual string GetTag(); + + // + // Retrieve Class Token ... + virtual string GetToken() + { + // + string result = NULL; + + // + string mType = GetTypeName(this); + + // + result = mType; + + // + string parts[]; + int partsCount = SplitContent( + parts, + result, + " " + // + ); + if (partsCount <= 0) + { + // + result = mType; + return result; + } + + // + bool hasLastPart = GetLastItem( + result, + parts + // + ); + if (!hasLastPart) + { + // + result = mType; + return result; + } + + // + return result; + } + +protected: + // + // Private ... +private: +}; diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.provider.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.provider.class.mq5 new file mode 100644 index 0000000..01fa0b9 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.provider.class.mq5 @@ -0,0 +1,10928 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSC121Provider +// Description: provides all Base Provider +// requirements For X121 ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... + +// +#include "../Helpers/x-saherelm.xcc.helper.mq5" +#include "../Helpers/x-saherelm.xct.helper.mq5" +#include "../Helpers/x-saherelm.xmc.helper.mq5" +#include "../Helpers/x-saherelm.xdon.helper.mq5" +#include "../Helpers/x-saherelm.xzg.helper.mq5" +#include "../Helpers/x-saherelm.xpv.helper.mq5" +#include "../Helpers/x-saherelm.xstr.helper.mq5" +#include "../Helpers/x-saherelm.xche.helper.mq5" +#include "../Helpers/x-saherelm.xosc.helper.mq5" +#include "../Helpers/x-saherelm.xtm.helper.mq5" +#include "../Helpers/x-saherelm.xama.helper.mq5" +#include "../Helpers/x-saherelm.xlh.helper.mq5" +#include "../Helpers/x-saherelm.xtd.helper.mq5" +#include "../Helpers/x-saherelm.xfi.helper.mq5" +#include "../Helpers/x-saherelm.xts.helper.mq5" +#include "../Helpers/x-saherelm.xrsi.helper.mq5" +#include "../Helpers/x-saherelm.xobd.helper.mq5" +#include "../Helpers/x-saherelm.xchlh.helper.mq5" +#include "../Helpers/x-saherelm.xchma.helper.mq5" + +// +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Classes/x-saherelm.x121.xmcycle.class.mq5" + +// +// Definitions ... + +// +// Signallers ... +enum ENUM_X121_SIGNAL_PROVIDERS +{ + // + PROVIDER_NONE, + XSP, + XTEST, + X786, + X121, + X110, + X92, + X128, + // + XTD, + XTAM, + XSI, + XTSFI, + XOBDLH, + XCHMACC, + XCHMAMN, + XCHMAMX, +}; + +// +// X121 Provider Inputs ... +class X121ProviderInputs : public XSCBaseProviderInpts +{ + // + // Public ... +public: + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + // S Market ... + ENUM_TIMEFRAMES sMarketPeriod; // Short Market Period + ENUM_X_PERIOD_METHOD sMarketMethod; // Short Market Period Method + string sMarketPrefix; // Short Market Prefix + + // + // MEDIUM Market ... + ENUM_TIMEFRAMES mMarketPeriod; // Medium Market Period + ENUM_X_PERIOD_METHOD mMarketMethod; // Medium Market Period Method + string mMarketPrefix; // Medium Market Prefix + + // + // LONG Market ... + ENUM_TIMEFRAMES lMarketPeriod; // Long Market Period + ENUM_X_PERIOD_METHOD lMarketMethod; // Long Market Period Method + string lMarketPrefix; // Long Market Prefix + + // + // HIND Market ... + ENUM_TIMEFRAMES hMarketPeriod; // Hind Market Period + ENUM_X_PERIOD_METHOD hMarketMethod; // Hind Market Period Method + string hMarketPrefix; // Hind Market Prefix + + // + // Indicators ... + XCCInputs ccInputs; + XCTInputs ctInputs; + XZGInputs zgInputs; + XPVInputs pvInputs; + XHKInputs hkInputs; + XMCInputs mcInputs; + XMRBInputs mrbInputs; + XICHInputs ichInputs; + XCHEInputs cheInputs; + XSTRInputs strInputs; + XDONInputs donInputs; + XOSCInputs oscInputs; + + // + XTSInputs tsInputs; + XTMInputs tmInputs; + XLHInputs lhInputs; + XTDInputs tdInputs; + XFIInputs fiInputs; + XOBDInputs obdInputs; + XAMAInputs amaInputs; + XRSIInputs rsiInputs; + XCHLHInputs chlhInputs; + XCHMAInputs chmaInputs; + + // + X121MCycleInputs cMarketInputs; // Curent Market Inputs + X121MCycleInputs sMarketInputs; // Short Market Inputs + X121MCycleInputs mMarketInputs; // Medium Market Inputs + X121MCycleInputs lMarketInputs; // Long Market Inputs + X121MCycleInputs hMarketInputs; // Hind Market Inputs + + // + // Tools ... + + // + // Initialize Input ... + bool Init() + { + // + bool result = false; + + // + // Validate Base Requirements ... + result = + // + IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(sMarketMethod, sMarketPeriod) && + IsSpecifiedValid(mMarketMethod, mMarketPeriod) && + IsSpecifiedValid(lMarketMethod, lMarketPeriod) && + IsSpecifiedValid(hMarketMethod, hMarketPeriod) + // + ; + if (!result) + { + return result; + } + + // + if (!zgInputs.IsValid()) + { + zgInputs.Default(); + } + if (!pvInputs.IsValid()) + { + pvInputs.Default(); + } + if (!mcInputs.IsValid()) + { + mcInputs.Default(); + } + if (!hkInputs.IsValid()) + { + hkInputs.Default(); + } + if (!mrbInputs.IsValid()) + { + mrbInputs.Default(); + } + if (!cheInputs.IsValid()) + { + cheInputs.Default(); + } + if (!strInputs.IsValid()) + { + strInputs.Default(); + } + if (!donInputs.IsValid()) + { + donInputs.Default(); + } + if (!oscInputs.IsValid()) + { + oscInputs.Default(); + } + if (!ichInputs.IsValid()) + { + ichInputs.Default(); + } + + // + if (!tsInputs.IsValid()) + { + tsInputs.Default(); + } + if (!tmInputs.IsValid()) + { + tmInputs.Default(); + } + if (!lhInputs.IsValid()) + { + lhInputs.Default(); + } + if (!tdInputs.IsValid()) + { + tdInputs.Default(); + } + if (!fiInputs.IsValid()) + { + fiInputs.Default(); + } + if (!obdInputs.IsValid()) + { + obdInputs.Default(); + } + if (!amaInputs.IsValid()) + { + amaInputs.Default(); + } + if (!rsiInputs.IsValid()) + { + rsiInputs.Default(); + } + if (!chlhInputs.IsValid()) + { + chlhInputs.Default(); + } + if (!chmaInputs.IsValid()) + { + chmaInputs.Default(); + } + + // + // Initialize Market Inputs ... + + // + // Current ... + cMarketInputs.pvInputs = this.pvInputs; + cMarketInputs.zgInputs = this.zgInputs; + cMarketInputs.tdInputs = this.tdInputs; + cMarketInputs.mcInputs = this.mcInputs; + cMarketInputs.hkInputs = this.hkInputs; + cMarketInputs.mrbInputs = this.mrbInputs; + cMarketInputs.strInputs = this.strInputs; + cMarketInputs.oscInputs = this.oscInputs; + cMarketInputs.cheInputs = this.cheInputs; + cMarketInputs.ichInputs = this.ichInputs; + cMarketInputs.donInputs = this.donInputs; + result = cMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_SHORT, + this.period, + X_PERIOD_MANUALLY, + "HOST", + false // + ); + if (!result) + { + return result; + } + + // + // Short ... + sMarketInputs.pvInputs = this.pvInputs; + sMarketInputs.zgInputs = this.zgInputs; + sMarketInputs.tdInputs = this.tdInputs; + sMarketInputs.mcInputs = this.mcInputs; + sMarketInputs.hkInputs = this.hkInputs; + sMarketInputs.mrbInputs = this.mrbInputs; + sMarketInputs.strInputs = this.strInputs; + sMarketInputs.oscInputs = this.oscInputs; + sMarketInputs.cheInputs = this.cheInputs; + sMarketInputs.ichInputs = this.ichInputs; + sMarketInputs.donInputs = this.donInputs; + result = sMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_SHORT, + this.sMarketPeriod, + this.sMarketMethod, + this.sMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + // Medium ... + mMarketInputs.pvInputs = this.pvInputs; + mMarketInputs.zgInputs = this.zgInputs; + mMarketInputs.tdInputs = this.tdInputs; + mMarketInputs.mcInputs = this.mcInputs; + mMarketInputs.hkInputs = this.hkInputs; + mMarketInputs.mrbInputs = this.mrbInputs; + mMarketInputs.strInputs = this.strInputs; + mMarketInputs.oscInputs = this.oscInputs; + mMarketInputs.cheInputs = this.cheInputs; + mMarketInputs.ichInputs = this.ichInputs; + mMarketInputs.donInputs = this.donInputs; + result = mMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_MEDIUM, + this.mMarketPeriod, + this.mMarketMethod, + this.mMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + // Long ... + lMarketInputs.pvInputs = this.pvInputs; + lMarketInputs.zgInputs = this.zgInputs; + lMarketInputs.tdInputs = this.tdInputs; + lMarketInputs.mcInputs = this.mcInputs; + lMarketInputs.hkInputs = this.hkInputs; + lMarketInputs.mrbInputs = this.mrbInputs; + lMarketInputs.strInputs = this.strInputs; + lMarketInputs.oscInputs = this.oscInputs; + lMarketInputs.cheInputs = this.cheInputs; + lMarketInputs.ichInputs = this.ichInputs; + lMarketInputs.donInputs = this.donInputs; + result = lMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_LONG, + this.lMarketPeriod, + this.lMarketMethod, + this.lMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + // Hind ... + hMarketInputs.pvInputs = this.pvInputs; + hMarketInputs.zgInputs = this.zgInputs; + hMarketInputs.tdInputs = this.tdInputs; + hMarketInputs.mcInputs = this.mcInputs; + hMarketInputs.hkInputs = this.hkInputs; + hMarketInputs.mrbInputs = this.mrbInputs; + hMarketInputs.strInputs = this.strInputs; + hMarketInputs.oscInputs = this.oscInputs; + hMarketInputs.cheInputs = this.cheInputs; + hMarketInputs.ichInputs = this.ichInputs; + hMarketInputs.donInputs = this.donInputs; + result = hMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_HIND, + this.hMarketPeriod, + this.hMarketMethod, + this.hMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + + // + return result; + } + + // + // Validate Input ... + bool IsValid() override + { + // + bool result = false; + + // + result = + // + // + IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(sMarketMethod, sMarketPeriod) && + IsSpecifiedValid(mMarketMethod, mMarketPeriod) && + IsSpecifiedValid(lMarketMethod, lMarketPeriod) && + IsSpecifiedValid(hMarketMethod, hMarketPeriod) && + // + ccInputs.IsValid() && + ctInputs.IsValid() && + zgInputs.IsValid() && + pvInputs.IsValid() && + mcInputs.IsValid() && + hkInputs.IsValid() && + mrbInputs.IsValid() && + cheInputs.IsValid() && + strInputs.IsValid() && + donInputs.IsValid() && + oscInputs.IsValid() && + ichInputs.IsValid() && + // + tsInputs.IsValid() && + tmInputs.IsValid() && + lhInputs.IsValid() && + tdInputs.IsValid() && + fiInputs.IsValid() && + obdInputs.IsValid() && + amaInputs.IsValid() && + rsiInputs.IsValid() && + chlhInputs.IsValid() && + chmaInputs.IsValid() && + // + cMarketInputs.IsValid() && + sMarketInputs.IsValid() && + mMarketInputs.IsValid() && + lMarketInputs.IsValid() && + hMarketInputs.IsValid() + // + ; + + // + return result; + } + + // + // Cleanup ... + void Clean() override + { + // + symbol = NULL; + period = NULL; + + // + sMarketPeriod = NULL; + sMarketMethod = X_PERIOD_NOTHING; + sMarketPrefix = NULL; + + // + mMarketPeriod = NULL; + mMarketMethod = X_PERIOD_NOTHING; + mMarketPrefix = NULL; + + // + lMarketPeriod = NULL; + lMarketMethod = X_PERIOD_NOTHING; + lMarketPrefix = NULL; + + // + hMarketPeriod = NULL; + hMarketMethod = X_PERIOD_NOTHING; + hMarketPrefix = NULL; + + // + ccInputs.Clean(); + ctInputs.Clean(); + zgInputs.Clean(); + pvInputs.Clean(); + mcInputs.Clean(); + hkInputs.Clean(); + mrbInputs.Clean(); + cheInputs.Clean(); + strInputs.Clean(); + donInputs.Clean(); + oscInputs.Clean(); + ichInputs.Clean(); + // + tsInputs.Clean(); + tmInputs.Clean(); + lhInputs.Clean(); + tdInputs.Clean(); + fiInputs.Clean(); + obdInputs.Clean(); + amaInputs.Clean(); + rsiInputs.Clean(); + chlhInputs.Clean(); + chmaInputs.Clean(); + // + cMarketInputs.Clean(); + sMarketInputs.Clean(); + mMarketInputs.Clean(); + lMarketInputs.Clean(); + hMarketInputs.Clean(); + } + + // + // Default ... + void Default() override + { + // + symbol = NULL; + period = NULL; + + // + sMarketPeriod = NULL; + sMarketMethod = X_PERIOD_AUTO; + sMarketPrefix = NULL; + + // + mMarketPeriod = NULL; + mMarketMethod = X_PERIOD_AUTO; + mMarketPrefix = NULL; + + // + lMarketPeriod = NULL; + lMarketMethod = X_PERIOD_AUTO; + lMarketPrefix = NULL; + + // + hMarketPeriod = NULL; + hMarketMethod = X_PERIOD_AUTO; + hMarketPrefix = NULL; + + // + ccInputs.Default(); + ctInputs.Default(); + zgInputs.Default(); + pvInputs.Default(); + mcInputs.Default(); + hkInputs.Default(); + mrbInputs.Default(); + cheInputs.Default(); + strInputs.Default(); + donInputs.Default(); + oscInputs.Default(); + ichInputs.Default(); + tsInputs.Default(); + tmInputs.Default(); + lhInputs.Default(); + tdInputs.Default(); + fiInputs.Default(); + obdInputs.Default(); + amaInputs.Default(); + rsiInputs.Default(); + chlhInputs.Default(); + chmaInputs.Default(); + cMarketInputs.Default(); + sMarketInputs.Default(); + mMarketInputs.Default(); + lMarketInputs.Default(); + hMarketInputs.Default(); + } + + // + // Max ... + int Max() override + { + // + int result = 0; + + // + result = MathMax(lhInputs.Max(), tmInputs.Max()); + + // + result = MathMax(result, tsInputs.Max()); + result = MathMax(result, ctInputs.Max()); + result = MathMax(result, ccInputs.Max()); + result = MathMax(result, tdInputs.Max()); + result = MathMax(result, fiInputs.Max()); + result = MathMax(result, obdInputs.Max()); + result = MathMax(result, amaInputs.Max()); + result = MathMax(result, rsiInputs.Max()); + result = MathMax(result, chlhInputs.Max()); + result = MathMax(result, chmaInputs.Max()); + + // + return result; + } + + // + // Set Symbol ... + bool SetSymbol(string value) + { + // + bool result = false; + + // + result = IsSpecifiedValid(value); + if (!result) + { + return result; + } + + // + symbol = value; + cMarketInputs.cycle.symbol = value; + sMarketInputs.cycle.symbol = value; + mMarketInputs.cycle.symbol = value; + lMarketInputs.cycle.symbol = value; + hMarketInputs.cycle.symbol = value; + + // + return result; + } + + // + // Set Period ... + bool SetPeriod(ENUM_TIMEFRAMES value) + { + // + bool result = false; + + // + result = IsSpecifiedValid(value); + if (!result) + { + return result; + } + + // + period = value; + cMarketInputs.cycle.period = value; + sMarketInputs.cycle.period = value; + mMarketInputs.cycle.period = value; + lMarketInputs.cycle.period = value; + hMarketInputs.cycle.period = value; + + // + return result; + } + + // +}; + +// +// X121 Provider Market Conditions ... +class X121MarketConditions : public XSCBaseProviderMarketConditions +{ + // + // Public ... +public: + // + + // + // XTS ... + double tsCurrents[]; + double tsNearests[]; + double tsMediests[]; + double tsFarests[]; + + // + // XFI ... + double fis[]; + + // + // XTD ... + double tdBullishs[]; + double tdBearishs[]; + double tdSignals[]; + + // + // XLH ... + double lhHhs[]; + double lhLls[]; + double lhSignals[]; + + // + // XTM ... + double tms[]; + + // + // XAMA ... + double amas[]; + + // + // XOBD ... + double obds[]; + + // + // XRSI ... + double rsis[]; + + // + // XCHMA ... + double chmaScFasts[]; + double chmaScSlows[]; + double chmaMcFasts[]; + double chmaMcSlows[]; + double chmaLcFasts[]; + double chmaLcSlows[]; + double chmaHotStates[]; + + // + // XCHLH ... + double chlhScHHs[]; + double chlhScLLs[]; + double chlhMcHHs[]; + double chlhMcLLs[]; + double chlhLcHHs[]; + double chlhLcLLs[]; + double chlhHotStates[]; + + // + // Conditional Variables ... + + // + // XTM ... + bool isXTMPeak; + bool isXTMVale; + bool isXTMBullish; + bool isXTMBearish; + bool isXTMNeutural; + bool isXTMEndBullish; + bool isXTMEndBearish; + bool isXTMStartBullish; + bool isXTMStartBearish; + bool isXTMEndBullishByNeutural; + bool isXTMEndBearishByNeutural; + bool isXTMStartBullishAfterNeutural; + bool isXTMStartBearishAfterNeutural; + + // + // XAMA ... + bool isXAMAPeak; + bool isXAMAVale; + bool isXAMABullish; + bool isXAMABearish; + bool isXAMANeutural; + bool isXAMAEndBullish; + bool isXAMAEndBearish; + bool isXAMAStartBullish; + bool isXAMAStartBearish; + bool isXAMAEndBullishByNeutural; + bool isXAMAEndBearishByNeutural; + bool isXAMAStartBullishAfterNeutural; + bool isXAMAStartBearishAfterNeutural; + + // + // XLH ... + bool isXLHHHIncreased; + bool isXLHHHDecreased; + bool isXLHLLIncreased; + bool isXLHLLDecreased; + bool isXLHLowAttachedLL; + bool isXLHHighAttachedHH; + bool isXLHHHSameInLength; + bool isXLHLLSameInLength; + bool isXLHPriceOverSignal; + bool isXLHPriceUnderSignal; + bool isXLHPriceInSignalRange; + bool isXLHPriceCrossedOverSignal; + bool isXLHPriceCrossedUnderSignal; + + // + // XTD ... + bool isXTDSignalPeak; + bool isXTDSignalVale; + bool isXTDBullishPeak; + bool isXTDBullishVale; + bool isXTDBearishPeak; + bool isXTDBearishVale; + bool isXTDBullOverBear; + bool isXTDBullUnderBear; + bool isXTDSignalOverBear; + bool isXTDSignalUnderBear; + bool isXTDBullCrossedOverBear; + bool isXTDBullCrossedUnderBear; + bool isXTDSignalCrossedOverBear; + bool isXTDSignalCrossedUnderBear; + + // + // XFI ... + bool isXFIPeak; + bool isXFIVale; + bool isXFICrossedOverZero; + bool isXFIOverZero; + bool isXFICrossedUnderZero; + bool isXFIUnderZero; + + // + // XTS ... + bool isXTSAllSame; + bool isXTSCurrentMin; + bool isXTSCurrentMax; + bool isXTSCurrentOverFarest; + bool isXTSCurrentOverNearest; + bool isXTSCurrentOverMediest; + bool isXTSCurrentUnderFarest; + bool isXTSCurrentUnderNearest; + bool isXTSCurrentUnderMediest; + bool isXTSCurrentCrossedOverFarest; + bool isXTSCurrentCrossedOverNearest; + bool isXTSCurrentCrossedOverMediest; + bool isXTSCurrentCrossedUnderFarest; + bool isXTSCurrentCrossedUnderNearest; + bool isXTSCurrentCrossedUnderMediest; + + // + // XRSI ... + bool isXRSIPeak; + bool isXRSIVale; + bool isXRSICrossedOverLongExit; + bool isXRSICrossedOverLongEntry; + bool isXRSICrossedUnderShortExit; + bool isXRSICrossedUnderShortEntry; + + // + // XOBD ... + bool isXOBDSwingLow; + bool isXOBDSwingHigh; + + // + // XCHLH ... + // + bool isXCHLHSameHHs; + bool isXCHLHSameLLs; + // + bool isXCHLHSCMCHHSame; + bool isXCHLHSCMCLLSame; + // + bool isXCHLHSCLCHHSame; + bool isXCHLHSCLCLLSame; + // + bool isXCHLHMCLCHHSame; + bool isXCHLHMCLCLLSame; + // + bool isXCHLHMCOnTopOfLC; + bool isXCHLHMCInBottomOfLC; + + // + // XCHMA ... + // + bool isXCHMASCOverMax; + bool isXCHMASCOverMin; + bool isXCHMASCUnderMax; + bool isXCHMASCUnderMin; + // + bool isXCHMASCCrossedOverMax; + bool isXCHMASCCrossedUnderMax; + bool isXCHMASCCrossedOverMin; + bool isXCHMASCCrossedUnderMin; + // + bool isXCHMASCPeak; + bool isXCHMASCVale; + bool isXCHMASCTrendsUp; + bool isXCHMASCTrendsDown; + bool isXCHMASCFastOverSlow; + bool isXCHMASCFastUnderSlow; + bool isXCHMASCFastCrossedOverSlow; + bool isXCHMASCFastCrossedUnderSlow; + // + bool isXCHMAMCPeak; + bool isXCHMAMCVale; + bool isXCHMAMCTrendsUp; + bool isXCHMAMCTrendsDown; + bool isXCHMAMCFastOverSlow; + bool isXCHMAMCFastUnderSlow; + bool isXCHMAMCFastCrossedOverSlow; + bool isXCHMAMCFastCrossedUnderSlow; + // + bool isXCHMALCPeak; + bool isXCHMALCVale; + bool isXCHMALCTrendsUp; + bool isXCHMALCTrendsDown; + bool isXCHMALCFastOverSlow; + bool isXCHMALCFastUnderSlow; + bool isXCHMALCFastCrossedOverSlow; + bool isXCHMALCFastCrossedUnderSlow; + + // + X121MCycleConditions cMarketConditions; // Current Market Conditions + X121MCycleConditions sMarketConditions; // Short Market Conditions + X121MCycleConditions mMarketConditions; // Medium Market Conditions + X121MCycleConditions lMarketConditions; // Long Market Conditions + X121MCycleConditions hMarketConditions; // Hind Market Conditions + + // + // Tools ... + + // + // Cleanup ... + void Clear() + { + // + symbol = NULL; + period = NULL; + + // + Clean(bars); + + // + ArraySetAsSeries(bars, true); + + // + cMarketConditions.Clear(); + sMarketConditions.Clear(); + mMarketConditions.Clear(); + lMarketConditions.Clear(); + hMarketConditions.Clear(); + } + + // + void GenerateScore( + double &bullishScore, // Bullish Score + double &bearishScore, // Bearish Score + double cMarketMultiplier = 1, // Current Market Score Multiplier + double sMarketMultiplier = 1.1, // Short Market Score Multiplier + double mMarketMultiplier = 1.2, // Medium Market Score Multiplier + double lMarketMultiplier = 1.6, // Long Market Score Multiplier + double hMarketMultiplier = 1.8 // Hind Market Score Multiplier + ) + { + // + double bullScore = 0; + double bearScore = 0; + + // + // XTM ... + + // + if (isXTMPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTMVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTMBullish) + { + bullScore++; + } + + // + if (isXTMBearish) + { + bearScore++; + } + + // + if (isXTMNeutural) + { + } + + // + if (isXTMEndBullish) + { + bearScore++; + } + + // + if (isXTMEndBearish) + { + bullScore++; + } + + // + if (isXTMStartBullish) + { + bullScore++; + } + + // + if (isXTMStartBearish) + { + bearScore++; + } + + // + if (isXTMEndBullishByNeutural) + { + bearScore++; + } + + // + if (isXTMEndBearishByNeutural) + { + bullScore++; + } + + // + if (isXTMStartBullishAfterNeutural) + { + bullScore++; + } + + // + if (isXTMStartBearishAfterNeutural) + { + bearScore++; + } + + // + // XAMA ... + + // + if (isXAMAPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXAMAVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXAMABullish) + { + bullScore++; + } + + // + if (isXAMABearish) + { + bearScore++; + } + + // + if (isXAMANeutural) + { + } + + // + if (isXAMAEndBullish) + { + bearScore++; + } + + // + if (isXAMAEndBearish) + { + bullScore++; + } + + // + if (isXAMAStartBullish) + { + bullScore++; + } + + // + if (isXAMAStartBearish) + { + bearScore++; + } + + // + if (isXAMAEndBullishByNeutural) + { + bearScore++; + } + + // + if (isXAMAEndBearishByNeutural) + { + bullScore++; + } + + // + if (isXAMAStartBullishAfterNeutural) + { + bullScore++; + } + + // + if (isXAMAStartBearishAfterNeutural) + { + bearScore++; + } + + // + // XLH ... + + // + if (isXLHHHIncreased) + { + // + bullScore--; + bearScore++; + } + + // + if (isXLHHHDecreased) + { + // + bullScore++; + bearScore--; + } + + // + if (isXLHLLIncreased) + { + // + bullScore++; + bearScore--; + } + + // + if (isXLHLLDecreased) + { + // + bullScore--; + bearScore++; + } + + // + if (isXLHLowAttachedLL) + { + // + bullScore++; + bearScore--; + } + + // + if (isXLHHighAttachedHH) + { + // + bullScore--; + bearScore++; + } + + // + if (isXLHHHSameInLength) + { + } + + // + if (isXLHLLSameInLength) + { + } + + // + if (isXLHPriceOverSignal) + { + bullScore++; + } + + // + if (isXLHPriceUnderSignal) + { + bearScore++; + } + + // + if (isXLHPriceInSignalRange) + { + } + + // + if (isXLHPriceCrossedOverSignal) + { + // + bullScore++; + bearScore--; + } + + // + if (isXLHPriceCrossedUnderSignal) + { + // + bullScore--; + bearScore++; + } + + // + // XTD ... + + // + if (isXTDSignalPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDSignalVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBullishPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDBullishVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBearishPeak) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBearishVale) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDBullOverBear) + { + bullScore++; + } + + // + if (isXTDBullUnderBear) + { + bearScore++; + } + + // + if (isXTDSignalOverBear) + { + bullScore++; + } + + // + if (isXTDSignalUnderBear) + { + bearScore++; + } + + // + if (isXTDBullCrossedOverBear) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBullCrossedUnderBear) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDSignalCrossedOverBear) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDSignalCrossedUnderBear) + { + // + bullScore--; + bearScore++; + } + + // + // XFI ... + + // + if (isXFIPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXFIVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXFICrossedOverZero) + { + // + bullScore++; + bearScore--; + } + + // + if (isXFIOverZero) + { + bullScore++; + } + + // + if (isXFICrossedUnderZero) + { + // + bullScore--; + bearScore++; + } + + // + if (isXFIUnderZero) + { + bearScore++; + } + + // + // XTS ... + + // + if (isXTSAllSame) + { + } + + // + if (isXTSCurrentMin) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTSCurrentMax) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTSCurrentOverFarest) + { + bullScore--; + } + + // + if (isXTSCurrentOverNearest) + { + bullScore--; + } + + // + if (isXTSCurrentOverMediest) + { + bullScore--; + } + + // + if (isXTSCurrentUnderFarest) + { + bearScore--; + } + + // + if (isXTSCurrentUnderNearest) + { + bearScore--; + } + + // + if (isXTSCurrentUnderMediest) + { + bearScore--; + } + + // + if (isXTSCurrentCrossedOverFarest) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTSCurrentCrossedOverNearest) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTSCurrentCrossedOverMediest) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTSCurrentCrossedUnderFarest) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTSCurrentCrossedUnderNearest) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTSCurrentCrossedUnderMediest) + { + // + bullScore--; + bearScore++; + } + + // + // XSI ... + + // + if (isXRSIPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXRSIVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXRSICrossedOverLongExit) + { + // + bullScore--; + bearScore++; + } + + // + if (isXRSICrossedOverLongEntry) + { + // + bullScore++; + bearScore--; + } + + // + if (isXRSICrossedUnderShortExit) + { + // + bullScore++; + bearScore--; + } + + // + if (isXRSICrossedUnderShortEntry) + { + // + bullScore--; + bearScore++; + } + + // + // XOBD ... + + // + if (isXOBDSwingLow) + { + bullScore++; + } + + // + if (isXOBDSwingHigh) + { + bearScore++; + } + + // + // XCHLH ... + + // + if (isXCHLHSameHHs) + { + bearScore++; + } + + // + if (isXCHLHSameLLs) + { + bullScore++; + } + + // + if (isXCHLHSCMCHHSame) + { + bearScore++; + } + + // + if (isXCHLHSCMCLLSame) + { + bullScore++; + } + + // + if (isXCHLHSCLCHHSame) + { + bearScore++; + } + + // + if (isXCHLHSCLCLLSame) + { + bullScore++; + } + + // + if (isXCHLHMCLCHHSame) + { + bearScore++; + } + + // + if (isXCHLHMCLCLLSame) + { + bullScore++; + } + + // + if (isXCHLHMCOnTopOfLC) + { + } + + // + if (isXCHLHMCInBottomOfLC) + { + } + + // + // XCHMA ... + + // + if (isXCHMASCOverMax) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMASCOverMin) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMASCUnderMax) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMASCUnderMin) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMASCCrossedOverMax) + { + // + bearScore--; + bearScore++; + } + + // + if (isXCHMASCCrossedUnderMax) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMASCCrossedOverMin) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMASCCrossedUnderMin) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMASCPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMASCVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMASCTrendsUp) + { + // + if (isXCHMASCFastOverSlow) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMASCFastUnderSlow) + { + // + bullScore--; + bearScore++; + } + } + + // + if (isXCHMASCTrendsDown) + { + // + if (isXCHMASCFastOverSlow) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMASCFastUnderSlow) + { + // + bullScore++; + bearScore--; + } + } + + // + if (isXCHMASCFastOverSlow) + { + bearScore++; + } + + // + if (isXCHMASCFastUnderSlow) + { + bearScore++; + } + + // + if (isXCHMASCFastCrossedOverSlow) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMASCFastCrossedUnderSlow) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMAMCPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMAMCVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMAMCTrendsUp) + { + // + if (isXCHMAMCFastOverSlow) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMAMCFastUnderSlow) + { + // + bullScore--; + bearScore++; + } + } + + // + if (isXCHMAMCTrendsDown) + { + // + if (isXCHMAMCFastOverSlow) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMAMCFastUnderSlow) + { + // + bullScore++; + bearScore--; + } + } + + // + if (isXCHMAMCFastOverSlow) + { + bullScore++; + } + + // + if (isXCHMAMCFastUnderSlow) + { + bearScore++; + } + + // + if (isXCHMAMCFastCrossedOverSlow) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMAMCFastCrossedUnderSlow) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMALCPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMALCVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMALCTrendsUp) + { + // + if (isXCHMALCFastOverSlow) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMALCFastUnderSlow) + { + // + bullScore--; + bearScore++; + } + } + + // + if (isXCHMALCTrendsDown) + { + // + if (isXCHMALCFastOverSlow) + { + // + bullScore--; + bearScore++; + } + + // + if (isXCHMALCFastUnderSlow) + { + // + bullScore++; + bearScore--; + } + } + + // + if (isXCHMALCFastOverSlow) + { + bullScore++; + } + + // + if (isXCHMALCFastUnderSlow) + { + bearScore++; + } + + // + if (isXCHMALCFastCrossedOverSlow) + { + // + bullScore++; + bearScore--; + } + + // + if (isXCHMALCFastCrossedUnderSlow) + { + // + bullScore--; + bearScore++; + } + + // + // Current Market ... + double cMarketBullScore = 0; + double cMarketBearScore = 0; + cMarketConditions.GenerateScore( + cMarketBullScore, + cMarketBearScore, + cMarketMultiplier // + ); + + // + // Short Market ... + double sMarketBullScore = 0; + double sMarketBearScore = 0; + sMarketConditions.GenerateScore( + sMarketBullScore, + sMarketBearScore, + sMarketMultiplier // + ); + + // + // Medium Market ... + double mMarketBullScore = 0; + double mMarketBearScore = 0; + mMarketConditions.GenerateScore( + mMarketBullScore, + mMarketBearScore, + mMarketMultiplier // + ); + + // + // Long Market ... + double lMarketBullScore = 0; + double lMarketBearScore = 0; + lMarketConditions.GenerateScore( + lMarketBullScore, + lMarketBearScore, + lMarketMultiplier // + ); + + // + // Hind Market ... + double hMarketBullScore = 0; + double hMarketBearScore = 0; + hMarketConditions.GenerateScore( + hMarketBullScore, + hMarketBearScore, + hMarketMultiplier // + ); + + // + // Calculate Summary Scores ... + + // + bullishScore = + // + bullScore + + cMarketBullScore + + sMarketBullScore + + mMarketBullScore + + lMarketBullScore + + hMarketBullScore + // + ; + + // + bearishScore = + // + bearScore + + cMarketBearScore + + sMarketBearScore + + mMarketBearScore + + lMarketBearScore + + hMarketBearScore + // + ; + } + + // + virtual string GenerateSummary( + const bool onlySummary = false, // Only Generate Conditions Summary + double cMarketMultiplier = 1, // Current Market Score Multiplier + double sMarketMultiplier = 1.1, // Short Market Score Multiplier + double mMarketMultiplier = 1.2, // Medium Market Score Multiplier + double lMarketMultiplier = 1.6, // Long Market Score Multiplier + double hMarketMultiplier = 1.8, // Hind Market Score Multiplier + const string separator = "\n", // Separator + string provided = NULL, // Additional Info about Type, Provider and Symbol + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + double bullScore = 0; + double bearScore = 0; + GenerateScore( + bullScore, + bearScore, + cMarketMultiplier, + sMarketMultiplier, + mMarketMultiplier, + lMarketMultiplier, + hMarketMultiplier // + ); + + // + string commonStr = + // + "Commons: " + separator + + "-----------------------------" + separator + + "Symbol: " + symbol + separator + + "Period: " + ToString(period) + separator + + "Time: " + ToString(TimeCurrent()) + separator + + "-----------" + separator + + "Cycles: " + separator + + "-----------" + separator + + sMarketConditions.GetTitle() + separator + + mMarketConditions.GetTitle() + separator + + lMarketConditions.GetTitle() + separator + + hMarketConditions.GetTitle() + separator + + "-----------" + separator + + "Scores: " + separator + + "-----------" + separator + + "Bullish: " + ToString(bullScore) + separator + + "Bearish: " + ToString(bearScore) + separator + + "-----------------------------" + separator + + // + // TODO: Add Scores Later ... + separator + + "" + // + ; + + // + // XOBD ... + string obdStr = + // + ToString("isXOBDSwingLow", isXOBDSwingLow, ignoreFalseConditions) + + ToString("isXOBDSwingHigh", isXOBDSwingHigh, ignoreFalseConditions) + + "" + // + ; + obdStr = SetLabel("XOBD: ", obdStr, separator); + + // + // ToString("", , ignoreFalseConditions) + + + // + // XFI ... + string fiStr = + // + ToString("isXFIPeak", isXFIPeak, ignoreFalseConditions) + + ToString("isXFIVale", isXFIVale, ignoreFalseConditions) + + ToString("isXFICrossedOverZero", isXFICrossedOverZero, ignoreFalseConditions) + + ToString("isXFIOverZero", isXFIOverZero, ignoreFalseConditions) + + ToString("isXFICrossedUnderZero", isXFICrossedUnderZero, ignoreFalseConditions) + + ToString("isXFIUnderZero", isXFIUnderZero, ignoreFalseConditions) + + "" + // + ; + fiStr = SetLabel("XFI: ", fiStr, separator); + + // + // XRSI ... + string rsiStr = + // + ToString("isXRSIPeak", isXRSIPeak, ignoreFalseConditions) + + ToString("isXRSIVale", isXRSIVale, ignoreFalseConditions) + + ToString("isXRSICrossedOverLongExit", isXRSICrossedOverLongExit, ignoreFalseConditions) + + ToString("isXRSICrossedOverLongEntry", isXRSICrossedOverLongEntry, ignoreFalseConditions) + + ToString("isXRSICrossedUnderShortExit", isXRSICrossedUnderShortExit, ignoreFalseConditions) + + ToString("isXRSICrossedUnderShortEntry", isXRSICrossedUnderShortEntry, ignoreFalseConditions) + + "" + // + ; + rsiStr = SetLabel("XRSI: ", rsiStr, separator); + + // + // XTM ... + string tmStr = + // + ToString("isXTMPeak", isXTMPeak, ignoreFalseConditions) + + ToString("isXTMVale", isXTMVale, ignoreFalseConditions) + + ToString("isXTMBullish", isXTMBullish, ignoreFalseConditions) + + ToString("isXTMBearish", isXTMBearish, ignoreFalseConditions) + + ToString("isXTMNeutural", isXTMNeutural, ignoreFalseConditions) + + ToString("isXTMEndBullish", isXTMEndBullish, ignoreFalseConditions) + + ToString("isXTMEndBearish", isXTMEndBearish, ignoreFalseConditions) + + ToString("isXTMStartBullish", isXTMStartBullish, ignoreFalseConditions) + + ToString("isXTMStartBearish", isXTMStartBearish, ignoreFalseConditions) + + ToString("isXTMEndBullishByNeutural", isXTMEndBullishByNeutural, ignoreFalseConditions) + + ToString("isXTMEndBearishByNeutural", isXTMEndBearishByNeutural, ignoreFalseConditions) + + ToString("isXTMStartBullishAfterNeutural", isXTMStartBullishAfterNeutural, ignoreFalseConditions) + + ToString("isXTMStartBearishAfterNeutural", isXTMStartBearishAfterNeutural, ignoreFalseConditions) + + "" + // + ; + tmStr = SetLabel("XTM: ", tmStr, separator); + + // + // XAMA ... + string amaStr = + // + ToString("isXAMAPeak", isXAMAPeak, ignoreFalseConditions) + + ToString("isXAMAVale", isXAMAVale, ignoreFalseConditions) + + ToString("isXAMABullish", isXAMABullish, ignoreFalseConditions) + + ToString("isXAMABearish", isXAMABearish, ignoreFalseConditions) + + ToString("isXAMANeutural", isXAMANeutural, ignoreFalseConditions) + + ToString("isXAMAEndBullish", isXAMAEndBullish, ignoreFalseConditions) + + ToString("isXAMAEndBearish", isXAMAEndBearish, ignoreFalseConditions) + + ToString("isXAMAStartBullish", isXAMAStartBullish, ignoreFalseConditions) + + ToString("isXAMAStartBearish", isXAMAStartBearish, ignoreFalseConditions) + + ToString("isXAMAEndBullishByNeutural", isXAMAEndBullishByNeutural, ignoreFalseConditions) + + ToString("isXAMAEndBearishByNeutural", isXAMAEndBearishByNeutural, ignoreFalseConditions) + + ToString("isXAMAStartBullishAfterNeutural", isXAMAStartBullishAfterNeutural, ignoreFalseConditions) + + ToString("isXAMAStartBearishAfterNeutural", isXAMAStartBearishAfterNeutural, ignoreFalseConditions) + + "" + // + ; + amaStr = SetLabel("XAMA: ", amaStr, separator); + + // + // XLH ... + string lhStr = + // + ToString("isXLHHHIncreased", isXLHHHIncreased, ignoreFalseConditions) + + ToString("isXLHHHDecreased", isXLHHHDecreased, ignoreFalseConditions) + + ToString("isXLHLLIncreased", isXLHLLIncreased, ignoreFalseConditions) + + ToString("isXLHLLDecreased", isXLHLLDecreased, ignoreFalseConditions) + + ToString("isXLHLowAttachedLL", isXLHLowAttachedLL, ignoreFalseConditions) + + ToString("isXLHHighAttachedHH", isXLHHighAttachedHH, ignoreFalseConditions) + + ToString("isXLHHHSameInLength", isXLHHHSameInLength, ignoreFalseConditions) + + ToString("isXLHLLSameInLength", isXLHLLSameInLength, ignoreFalseConditions) + + ToString("isXLHPriceOverSignal", isXLHPriceOverSignal, ignoreFalseConditions) + + ToString("isXLHPriceUnderSignal", isXLHPriceUnderSignal, ignoreFalseConditions) + + ToString("isXLHPriceInSignalRange", isXLHPriceInSignalRange, ignoreFalseConditions) + + ToString("isXLHPriceCrossedOverSignal", isXLHPriceCrossedOverSignal, ignoreFalseConditions) + + ToString("isXLHPriceCrossedUnderSignal", isXLHPriceCrossedUnderSignal, ignoreFalseConditions) + + "" + // + ; + lhStr = SetLabel("XLH: ", lhStr, separator); + + // + // XTD ... + string tdStr = + // + ToString("isXTDSignalPeak", isXTDSignalPeak, ignoreFalseConditions) + + ToString("isXTDSignalVale", isXTDSignalVale, ignoreFalseConditions) + + ToString("isXTDBullishPeak", isXTDBullishPeak, ignoreFalseConditions) + + ToString("isXTDBullishVale", isXTDBullishVale, ignoreFalseConditions) + + ToString("isXTDBearishPeak", isXTDBearishPeak, ignoreFalseConditions) + + ToString("isXTDBearishVale", isXTDBearishVale, ignoreFalseConditions) + + ToString("isXTDBullOverBear", isXTDBullOverBear, ignoreFalseConditions) + + ToString("isXTDBullUnderBear", isXTDBullUnderBear, ignoreFalseConditions) + + ToString("isXTDSignalOverBear", isXTDSignalOverBear, ignoreFalseConditions) + + ToString("isXTDSignalUnderBear", isXTDSignalUnderBear, ignoreFalseConditions) + + ToString("isXTDBullCrossedOverBear", isXTDBullCrossedOverBear, ignoreFalseConditions) + + ToString("isXTDBullCrossedUnderBear", isXTDBullCrossedUnderBear, ignoreFalseConditions) + + ToString("isXTDSignalCrossedOverBear", isXTDSignalCrossedOverBear, ignoreFalseConditions) + + ToString("isXTDSignalCrossedUnderBear", isXTDSignalCrossedUnderBear, ignoreFalseConditions) + + "" + // + ; + tdStr = SetLabel("XTD: ", tdStr, separator); + + // + // XTS ... + string tsStr = + // + ToString("isXTSAllSame", isXTSAllSame, ignoreFalseConditions) + + ToString("isXTSCurrentMin", isXTSCurrentMin, ignoreFalseConditions) + + ToString("isXTSCurrentMax", isXTSCurrentMax, ignoreFalseConditions) + + ToString("isXTSCurrentOverFarest", isXTSCurrentOverFarest, ignoreFalseConditions) + + ToString("isXTSCurrentOverNearest", isXTSCurrentOverNearest, ignoreFalseConditions) + + ToString("isXTSCurrentOverMediest", isXTSCurrentOverMediest, ignoreFalseConditions) + + ToString("isXTSCurrentUnderFarest", isXTSCurrentUnderFarest, ignoreFalseConditions) + + ToString("isXTSCurrentUnderNearest", isXTSCurrentUnderNearest, ignoreFalseConditions) + + ToString("isXTSCurrentUnderMediest", isXTSCurrentUnderMediest, ignoreFalseConditions) + + ToString("isXTSCurrentCrossedOverFarest", isXTSCurrentCrossedOverFarest, ignoreFalseConditions) + + ToString("isXTSCurrentCrossedOverNearest", isXTSCurrentCrossedOverNearest, ignoreFalseConditions) + + ToString("isXTSCurrentCrossedOverMediest", isXTSCurrentCrossedOverMediest, ignoreFalseConditions) + + ToString("isXTSCurrentCrossedUnderFarest", isXTSCurrentCrossedUnderFarest, ignoreFalseConditions) + + ToString("isXTSCurrentCrossedUnderNearest", isXTSCurrentCrossedUnderNearest, ignoreFalseConditions) + + ToString("isXTSCurrentCrossedUnderMediest", isXTSCurrentCrossedUnderMediest, ignoreFalseConditions) + + "" + // + ; + tsStr = SetLabel("XTS: ", tsStr, separator); + + // + // XCHLH ... + string chlhStr = + // + ToString("isXCHLHSameHHs", isXCHLHSameHHs, ignoreFalseConditions) + + ToString("isXCHLHSameLLs", isXCHLHSameLLs, ignoreFalseConditions) + + ToString("isXCHLHSCMCHHSame", isXCHLHSCMCHHSame, ignoreFalseConditions) + + ToString("isXCHLHSCMCLLSame", isXCHLHSCMCLLSame, ignoreFalseConditions) + + ToString("isXCHLHSCLCHHSame", isXCHLHSCLCHHSame, ignoreFalseConditions) + + ToString("isXCHLHSCLCLLSame", isXCHLHSCLCLLSame, ignoreFalseConditions) + + ToString("isXCHLHMCLCHHSame", isXCHLHMCLCHHSame, ignoreFalseConditions) + + ToString("isXCHLHMCLCLLSame", isXCHLHMCLCLLSame, ignoreFalseConditions) + + ToString("isXCHLHMCOnTopOfLC", isXCHLHMCOnTopOfLC, ignoreFalseConditions) + + ToString("isXCHLHMCInBottomOfLC", isXCHLHMCInBottomOfLC, ignoreFalseConditions) + + "" + // + ; + chlhStr = SetLabel("XCHLH: ", chlhStr, separator); + + // + // XCHMA ... + string chmaStr = + // + ToString("isXCHMASCOverMax", isXCHMASCOverMax, ignoreFalseConditions) + + ToString("isXCHMASCOverMin", isXCHMASCOverMin, ignoreFalseConditions) + + ToString("isXCHMASCUnderMax", isXCHMASCUnderMax, ignoreFalseConditions) + + ToString("isXCHMASCUnderMin", isXCHMASCUnderMin, ignoreFalseConditions) + + ToString("isXCHMASCCrossedOverMax", isXCHMASCCrossedOverMax, ignoreFalseConditions) + + ToString("isXCHMASCCrossedUnderMax", isXCHMASCCrossedUnderMax, ignoreFalseConditions) + + ToString("isXCHMASCCrossedOverMin", isXCHMASCCrossedOverMin, ignoreFalseConditions) + + ToString("isXCHMASCCrossedUnderMin", isXCHMASCCrossedUnderMin, ignoreFalseConditions) + + ToString("isXCHMASCPeak", isXCHMASCPeak, ignoreFalseConditions) + + ToString("isXCHMASCVale", isXCHMASCVale, ignoreFalseConditions) + + ToString("isXCHMASCTrendsUp", isXCHMASCTrendsUp, ignoreFalseConditions) + + ToString("isXCHMASCTrendsDown", isXCHMASCTrendsDown, ignoreFalseConditions) + + ToString("isXCHMASCFastOverSlow", isXCHMASCFastOverSlow, ignoreFalseConditions) + + ToString("isXCHMASCFastUnderSlow", isXCHMASCFastUnderSlow, ignoreFalseConditions) + + ToString("isXCHMASCFastCrossedOverSlow", isXCHMASCFastCrossedOverSlow, ignoreFalseConditions) + + ToString("isXCHMASCFastCrossedUnderSlow", isXCHMASCFastCrossedUnderSlow, ignoreFalseConditions) + + ToString("isXCHMAMCPeak", isXCHMAMCPeak, ignoreFalseConditions) + + ToString("isXCHMAMCVale", isXCHMAMCVale, ignoreFalseConditions) + + ToString("isXCHMAMCTrendsUp", isXCHMAMCTrendsUp, ignoreFalseConditions) + + ToString("isXCHMAMCTrendsDown", isXCHMAMCTrendsDown, ignoreFalseConditions) + + ToString("isXCHMAMCFastOverSlow", isXCHMAMCFastOverSlow, ignoreFalseConditions) + + ToString("isXCHMAMCFastUnderSlow", isXCHMAMCFastUnderSlow, ignoreFalseConditions) + + ToString("isXCHMAMCFastCrossedOverSlow", isXCHMAMCFastCrossedOverSlow, ignoreFalseConditions) + + ToString("isXCHMAMCFastCrossedUnderSlow", isXCHMAMCFastCrossedUnderSlow, ignoreFalseConditions) + + ToString("isXCHMALCPeak", isXCHMALCPeak, ignoreFalseConditions) + + ToString("isXCHMALCVale", isXCHMALCVale, ignoreFalseConditions) + + ToString("isXCHMALCTrendsUp", isXCHMALCTrendsUp, ignoreFalseConditions) + + ToString("isXCHMALCTrendsDown", isXCHMALCTrendsDown, ignoreFalseConditions) + + ToString("isXCHMALCFastOverSlow", isXCHMALCFastOverSlow, ignoreFalseConditions) + + ToString("isXCHMALCFastUnderSlow", isXCHMALCFastUnderSlow, ignoreFalseConditions) + + ToString("isXCHMALCFastCrossedOverSlow", isXCHMALCFastCrossedOverSlow, ignoreFalseConditions) + + ToString("isXCHMALCFastCrossedUnderSlow", isXCHMALCFastCrossedUnderSlow, ignoreFalseConditions) + + "" + // + ; + chmaStr = SetLabel("XCHMA: ", chmaStr, separator); + + // + string cMarketConditionsStr = cMarketConditions.GenerateSummary(onlySummary, cMarketMultiplier); + string sMarketConditionsStr = sMarketConditions.GenerateSummary(onlySummary, sMarketMultiplier); + string mMarketConditionsStr = mMarketConditions.GenerateSummary(onlySummary, mMarketMultiplier); + string lMarketConditionsStr = lMarketConditions.GenerateSummary(onlySummary, lMarketMultiplier); + string hMarketConditionsStr = hMarketConditions.GenerateSummary(onlySummary, hMarketMultiplier); + + // + result = + // + "[" + GetToken() + "]" + separator + + (IsSpecifiedValid(provided) ? provided + separator : "") + + "-----------------------------" + separator + + commonStr + + (!onlySummary + ? obdStr + + fiStr + + rsiStr + + tmStr + + amaStr + + lhStr + + tdStr + + tsStr + + chlhStr + + chmaStr + + cMarketConditionsStr + + sMarketConditionsStr + + mMarketConditionsStr + + lMarketConditionsStr + + hMarketConditionsStr + + "" + : "") + + "" + // + ; + + // + return result; + } + + // + // For Data Collector ... + string GetToken() + { + return GetSpecificToken(this); + } + bool IsModelValid() + { + return false; + } + string ToModelString() + { + return NULL; + } + bool ParseModel(string content) + { + return false; + } + int FindIndex(X121MarketConditions &items[]) + { + return -1; + } +}; + +// +// Class ... + +// +// X121 Provider Class ... +class XSCX121Provider : public XSCBaseProvider +{ + // + // Public ... +public: + // + // Props ... + + // + XSCXCCHelper *ccHelper; // Candle Clear + XSCXCTHelper *ctHelper; // Candle Timer + + // + XSCXTSHelper *tsHelper; + XSCXFIHelper *fiHelper; + XSCXTDHelper *tdHelper; + XSCXLHHelper *lhHelper; + XSCXTMHelper *tmHelper; + XSCXOBDHelper *obdHelper; + XSCXRSIHelper *rsiHelper; + XSCXAMAHelper *amaHelper; + XSCXCHMAHelper *chmaHelper; + XSCXCHLHHelper *chlhHelper; + + // + XSCX121Market *cMarket; // Current Market + XSCX121Market *sMarket; // Short Market + XSCX121Market *mMarket; // Medium Market + XSCX121Market *lMarket; // Long Market + XSCX121Market *hMarket; // Hind Market + + // + // Constructor ... + XSCX121Provider( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + double staticVolume // Static Volume for Positions + + ) : XSCBaseProvider(symbol, period, staticVolume) + { + // + ccHelper = new XSCXCCHelper(); + ctHelper = new XSCXCTHelper(); + + // + tsHelper = new XSCXTSHelper(); + fiHelper = new XSCXFIHelper(); + tdHelper = new XSCXTDHelper(); + lhHelper = new XSCXLHHelper(); + tmHelper = new XSCXTMHelper(); + obdHelper = new XSCXOBDHelper(); + rsiHelper = new XSCXRSIHelper(); + amaHelper = new XSCXAMAHelper(); + chmaHelper = new XSCXCHMAHelper(); + chlhHelper = new XSCXCHLHHelper(); + + // + // Instantiate X121 Market Cycles Classes ... + cMarket = new XSCX121Market(); + sMarket = new XSCX121Market(); + mMarket = new XSCX121Market(); + lMarket = new XSCX121Market(); + hMarket = new XSCX121Market(); + + // + mNumberOfItems = 15; + mNumberOfSRVerified = 71; + mMinRequiredSupportAndResistances = 30; + } + + // + // Properties Gettr(s) / Setter(s) ... + + // + void SetNumberOfSRVerified(int value) + { + mNumberOfSRVerified = value; + } + + // + int GetNumberOfSRVerified() + { + return mNumberOfSRVerified; + } + + // + void SetNumberOfItems(int value) + { + mNumberOfItems = value; + } + + // + int GetNumberOfItems() + { + return mNumberOfItems; + } + + // + void SetMinRequiredSupportAndResistances(int value) + { + mMinRequiredSupportAndResistances = value; + } + + // + int GetMinRequiredSupportAndResistances() + { + return mMinRequiredSupportAndResistances; + } + + // + // Overrides ... + + // + // DeInit all Requirements ... + void DeInit() override + { + // + delete ccHelper; + delete ctHelper; + + // + delete tsHelper; + delete fiHelper; + delete tdHelper; + delete lhHelper; + delete tmHelper; + delete obdHelper; + delete rsiHelper; + delete amaHelper; + delete chmaHelper; + delete chlhHelper; + + // + delete cMarket; + delete sMarket; + delete mMarket; + delete lMarket; + delete hMarket; + } + + // + // Functions ... + + // + // Init all Requirements ... + bool Init(X121ProviderInputs &inputs) + { + // + bool result = false; + + // + // Validate ... + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + string mSymbol = GetSymbol(); + ENUM_TIMEFRAMES mPeriod = GetPeriod(); + + // + // Init Indicators Helpers ... + + // + // CT ... + result = ctHelper + .Init( + mSymbol, + mPeriod, + mInputs.ctInputs + // + ); + if (!result) + { + return result; + } + + // + // CC ... + result = ccHelper + .Init( + mSymbol, + mPeriod, + mInputs.ccInputs + // + ); + if (!result) + { + return result; + } + + // + result = tsHelper + .Init( + mSymbol, + mPeriod, + mInputs.tsInputs + // + ); + if (!result) + { + return result; + } + + // + result = fiHelper + .Init( + mSymbol, + mPeriod, + mInputs.fiInputs + // + ); + if (!result) + { + return result; + } + + // + result = tdHelper + .Init( + mSymbol, + mPeriod, + mInputs.tdInputs + // + ); + if (!result) + { + return result; + } + + // + result = lhHelper + .Init( + mSymbol, + mPeriod, + mInputs.lhInputs + // + ); + if (!result) + { + return result; + } + + // + result = tmHelper + .Init( + mSymbol, + mPeriod, + mInputs.tmInputs + // + ); + if (!result) + { + return result; + } + + // + result = obdHelper + .Init( + mSymbol, + mPeriod, + mInputs.obdInputs + // + ); + if (!result) + { + return result; + } + + // + result = rsiHelper + .Init( + mSymbol, + mPeriod, + mInputs.rsiInputs + // + ); + if (!result) + { + return result; + } + + // + result = amaHelper + .Init( + mSymbol, + mPeriod, + mInputs.amaInputs + // + ); + if (!result) + { + return result; + } + + // + result = chmaHelper + .Init( + mSymbol, + mPeriod, + mInputs.chmaInputs + // + ); + if (!result) + { + return result; + } + + // + result = chlhHelper + .Init( + mSymbol, + mPeriod, + mInputs.chlhInputs + // + ); + if (!result) + { + return result; + } + + // + // Initialize X121 Market Cycles ... + + // + // Current Market ... + result = cMarket + .Init(mInputs.cMarketInputs); + if (!result) + { + return result; + } + + // + // Short Market ... + result = sMarket + .Init(mInputs.sMarketInputs); + if (!result) + { + return result; + } + + // + // Medium Market ... + result = mMarket + .Init(mInputs.mMarketInputs); + if (!result) + { + return result; + } + + // + // Long Market ... + result = lMarket + .Init(mInputs.lMarketInputs); + if (!result) + { + return result; + } + + // + // Hind Market ... + result = hMarket + .Init(mInputs.hMarketInputs); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Set Default Position's Type ... + // Enable / Disable Long (Buy), Short (Sell) ... + void SetSignalTypeState( + ENUM_POSITION_TYPE type, // Which types are Signals be Targetted + bool state // Which State is going to Set + ) + { + // + if (IsLong(type)) + { + mIsLongEnable = state; + } + else + { + mIsShortEnable = state; + } + } + + // + // Set Signal Providers ... + void SetSignalProviderState( + ENUM_X121_SIGNAL_PROVIDERS provider, // Provider State + bool state // Which state is going to set ... + ) + { + // + if (provider == PROVIDER_NONE) + { + return; + } + + // + switch (provider) + { + // + case XSP: + mIsXSPSignalProviderEnable = state; + break; + + // + case XTEST: + mIsXTESTSignalProviderEnable = state; + break; + + // + case X786: + mIsX786SignalProviderEnable = state; + break; + + // + case X121: + mIsX121SignalProviderEnable = state; + break; + + // + case X110: + mIsX110SignalProviderEnable = state; + break; + + // + case X92: + mIsX92SignalProviderEnable = state; + break; + + // + case X128: + mIsX128SignalProviderEnable = state; + break; + + // + case XTD: + mIsXTDSignalProviderEnable = state; + break; + + // + case XTAM: + mIsXTAMSignalProviderEnable = state; + break; + + // + case XSI: + mIsXSISignalProviderEnable = state; + break; + + // + case XTSFI: + mIsXTSFISignalProviderEnable = state; + break; + + // + case XOBDLH: + mIsXOBDLHSignalProviderEnable = state; + break; + + // + case XCHMACC: + mIsXCHMACCSignalProviderEnable = state; + break; + + // + case XCHMAMN: + mIsXCHMAMNSignalProviderEnable = state; + break; + + // + case XCHMAMX: + mIsXCHMAMXSignalProviderEnable = state; + break; + } + } + + // + void SetSignalProviderStates( + ENUM_X121_SIGNAL_PROVIDERS &providers[], // Collection of Providers ... + bool state // Which state is going to set ... + ) + { + // + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + return; + } + + // + for (int i = 0; i < providersCount; i++) + { + SetSignalProviderState(providers[i], state); + } + } + + // + string GetTag() + { + // + string result = NULL; + + // + result = + // + GetToken() + + "[" + + GetSymbol() + + "," + + ToString(GetPeriod()) + + "]" + // + ; + + // + return result; + } + + // + void GetMarketConditions( + X121MarketConditions &mConditions, // Market Conditions Result + int barIndex = 0 // Specified Bar Index + ) + { + // + mConditions.Clear(); + + // + CalculateConditions(mConditions, barIndex); + } + + // + // Check Market For Signal ... + bool HasSignal( + int barIndex, + XSignal &mSignal, // Hold's Signal if Exists ... + X121MarketConditions &mConditions // Hold's Market Conditions ... + ) + { + // + bool result = false; + + // + // Validate Enable Process ... + result = !CanIgnoreProcess(); + if (!result) + { + return result; + } + + // + mWaitsUntilNewBar = false; + + // + // Validate Enable Type of Signalling ... + result = mIsLongEnable || mIsShortEnable; + if (!result) + { + return result; + } + + // + // Now we Have to Pass the Conditions to Each Signal Provider + // for Retrieving Signals Based On them ... + + // + // Reading Market Conditions ... + GetMarketConditions(mConditions, barIndex); + AddScores(mConditions); + + // + int signalPusher = 0; + bool hasLong = false; + bool hasShort = false; + string provider = ""; + + // + double providedSL = 0; + double providedTP = 0; + double providedR2r = 2; + + // + // Long ... + if (mIsLongEnable) + { + // + signalPusher = 0; + + // + hasLong = HasSpecificSignal( + barIndex, + POSITION_TYPE_BUY, + provider, + signalPusher, + mConditions, + providedSL, + providedTP, + providedR2r // + ); + } + + // + // Short ... + if (mIsShortEnable) + { + // + signalPusher = 0; + + // + hasShort = HasSpecificSignal( + barIndex, + POSITION_TYPE_SELL, + provider, + signalPusher, + mConditions, + providedSL, + providedTP, + providedR2r // + ); + } + + // + result = hasLong || hasShort; + if (!result) + { + return result; + } + + // + // Validate Longs Use Common Conditions ... + + // + // if (hasLong) + // { + // // + // int pusher = 0; + // result = HasBaseLongConditions( + // mConditions, + // pusher // + // ); + + // // + // if (!result) + // { + // return result; + // } + // } + + // // + // if (hasShort) + // { + // // + // int pusher = 0; + // result = HasBaseShortConditions( + // mConditions, + // pusher // + // ); + + // // + // if (!result) + // { + // return result; + // } + // } + + // + // Prepare Signal ... + + // + if (result) + { + // + // Here We Have to Prepare Signal ... + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + double tpPoint = 60; + double slPoint = 30; + double volume = GetStaticVolume(); // * signalPusher; + double tpPrice = PointToPrice( + tpPoint, + symbol // + ); + double slPrice = PointToPrice( + slPoint, + symbol // + ); + ENUM_POSITION_TYPE type = hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + double entry = GetEntry( + symbol, + type // + ); + + // + double tp = 0; + double sl = 0; + + // + ENUM_X_SIGNAL_MANAGING_ACTIONS action = X_SIGNAL_USE_NOTHING; + + // + // TODO: Make Configurable ... + double r2r = providedR2r; + if (r2r <= 0) + { + r2r = 1.5; + } + + // + sl = 0; + tp = 0; + + // + // TP based on SL and Risk to Reward ... + if (providedSL > 0) + { + // + sl = providedSL; + + // + double risk = MathAbs(entry - sl); + + // + double reward = risk * r2r; + + // + tp = hasLong + ? entry + reward + : entry - reward; + } + else + // + // SL based on TP and Risk to Reward ... + if (providedTP > 0) + { + // + tp = providedTP; + + // + double reward = MathAbs(entry - tp); + + // + double risk = reward / r2r; + + // + sl = hasLong + ? entry - risk + : entry + risk; + } + else + { + // + // TODOO: Remove this ... + sl = hasLong + ? sMarket.pv.GetMCLL(0) + : sMarket.pv.GetMCHH(0); + double risk = MathAbs(entry - sl); + double reward = risk * r2r; + tp = hasLong + ? entry + reward + : entry - reward; + } + + // + result = mSignal.Prepare( + symbol, + provider, + period, + type, + mode, + entry, + volume, + action, + sl, + tp + // + ); + + // + // Generate Support Signal for Specified Provider ... + if (result && provider == ToString(PROVIDER_NONE)) + { + // + double cKijunSen = cMarket.ich.GetKijunSen(0); + double sKijunSen = sMarket.ich.GetKijunSen(0); + double mKijunSen = mMarket.ich.GetKijunSen(0); + double lKijunSen = lMarket.ich.GetKijunSen(0); + double hKijunSen = hMarket.ich.GetKijunSen(0); + + // + double kijunSens[] = { + cKijunSen, + sKijunSen, + mKijunSen, + lKijunSen, + hKijunSen // + }; + + // + double lesserKijun = FindLesserThan( + entry, + kijunSens, + true // + ); + + // + double biggerKijun = FindBiggerThan( + entry, + kijunSens, + true // + ); + + // + ENUM_POSITION_TYPE sType = + hasLong + ? POSITION_TYPE_SELL + : POSITION_TYPE_BUY; + + bool isLongS = IsLong(sType); + + // + double sEntry = + isLongS + ? biggerKijun + : lesserKijun; + + // + double peakMin = GetMinPeaks(true); + double peakMax = GetMinPeaks(true); + double valeMin = GetMaxVales(true); + double valeMax = GetMaxVales(true); + + // + double sTP = + isLongS + ? peakMin + : valeMax; + + // + double sSL = + isLongS + ? valeMin + : peakMax; + + // + double sVolume = mSignal.volume * 2; + + // + // Prepare ... + XSignal sSignal; + bool isValid = sSignal.Prepare( + mSignal.symbol, + mSignal.provider, + mSignal.period, + sType, + X_ORDER_MODE_STOP, + sEntry, + sVolume, + X_SIGNAL_USE_NOTHING, + sSL, + sTP // + ); + if (isValid) + { + // + AddRef( + sSignal, + mSignal.supports // + ); + } + } + + // + if (result) + { + mWaitsUntilNewBar = true; + } + } + + // + UpdateSupportsAndResistances(); + + // + return result; + } + + // + // Check for any Guards ... + bool HasGuard(XGuard &guards[]) + { + // + bool result = false; + + // + // Try to Find Support and Resistances if Configured ... + FindSupportAndResistances(); + + // + // TODO: + + // + // Here We Have to Implement Trail Management for + // Spearate Providers ... + + // + // And also Remove EA Trail Manage ment inside EA ... + + // + return result; + } + + // + // Tools ... + + // + void Draw() + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + ulong chID = FindChartID( + symbol, + period); + if (chID < 0) + { + return; + } + + // + int subWindow = 0; + + // + int offset = 0; + + // + cMarket.Draw(chID, subWindow, offset); + sMarket.Draw(chID, subWindow, offset); + mMarket.Draw(chID, subWindow, offset); + lMarket.Draw(chID, subWindow, offset); + hMarket.Draw(chID, subWindow, offset); + } + + // + // Support and Resistances ... + + // + int CountSupportResistances() + { + return ArraySize(mSupportResistances); + } + + // + bool GenerateSupRes( + XOHCLSupRes &supRes, // SupRes Instance ... + ENUM_POSITION_TYPE type, // Position Type ... + int count = 5, + double step = 0, + bool useAtrAsStep = true // + ) + { + // + bool result = false; + + // + if (count <= 0) + { + count = 1; + } + + // + if (step <= 0) + { + // + if (useAtrAsStep) + { + step = cMarket.osc.GetATR(0); + } + else + { + step = 0; + } + } + + // + supRes.Clean(); + + // + double price = GetExit( + GetSymbol(), + type // + ); + + // + result = supRes.Init( + price, + mSupportResistances, + count, + step // + ); + + // + return result; + } + + // + bool GenerateLongSupRes( + XOHCLSupRes &supRes, // SupRes Instance ... + int count = 5, + double step = 0, + bool useAtrAsStep = true // + ) + { + // + bool result = false; + + // + result = GenerateSupRes( + supRes, + POSITION_TYPE_BUY, + count, + step, + useAtrAsStep // + ); + + // + return result; + } + + // + bool GenerateShortSupRes( + XOHCLSupRes &supRes, // SupRes Instance ... + int count = 5, + double step = 0, + bool useAtrAsStep = true // + ) + { + // + bool result = false; + + // + result = GenerateSupRes( + supRes, + POSITION_TYPE_BUY, + count, + step, + useAtrAsStep // + ); + + // + return result; + } + + // + // Peask and Vales Finder ... + + // + void GetPeaks( + double &peaks[], + bool ignoreCurrent = false // + ) + { + // + Clean(peaks); + + // + // + double cPVPeak = cMarket.pv.GetPeak(0); + double sPeak = sMarket.pv.GetPeak(0); + double mPeak = mMarket.pv.GetPeak(0); + double lPeak = lMarket.pv.GetPeak(0); + double hPeak = hMarket.pv.GetPeak(0); + + // + double mPeaks[] = { + cPVPeak, + sPeak, + mPeak, + lPeak, + hPeak // + }; + + // + if (ignoreCurrent) + { + // + Remove( + cPVPeak, + mPeaks // + ); + } + + // + Copy( + mPeaks, + peaks // + ); + } + + // + void GetVales( + double &vales[], + bool ignoreCurrent = false // + ) + { + // + Clean(vales); + + // + double cPVVale = cMarket.pv.GetVale(0); + double sVale = sMarket.pv.GetVale(0); + double mVale = mMarket.pv.GetVale(0); + double lVale = lMarket.pv.GetVale(0); + double hVale = hMarket.pv.GetVale(0); + + // + double mVales[] = { + cPVVale, + sVale, + mVale, + lVale, + hVale // + }; + + // + if (ignoreCurrent) + { + // + Remove( + cPVVale, + mVales // + ); + } + + // + Copy( + mVales, + vales // + ); + } + + // + double GetMinPeaks(bool ignoreCurrent = false) + { + // + double peaks[]; + GetPeaks( + peaks, + ignoreCurrent // + ); + + // + double minPeak = GetMin(peaks); + double maxPeak = GetMax(peaks); + + // + return minPeak; + } + + // + double GetMaxPeaks(bool ignoreCurrent = false) + { + // + double peaks[]; + GetPeaks( + peaks, + ignoreCurrent // + ); + + // + double minPeak = GetMin(peaks); + double maxPeak = GetMax(peaks); + + // + return maxPeak; + } + + // + double GetMinVales(bool ignoreCurrent = false) + { + // + double vales[]; + GetVales( + vales, + ignoreCurrent // + ); + + // + double minVale = GetMin(vales); + double maxVale = GetMax(vales); + + // + return minVale; + } + + // + double GetMaxVales(bool ignoreCurrent = false) + { + // + double vales[]; + GetVales( + vales, + ignoreCurrent // + ); + + // + double minVale = GetMin(vales); + double maxVale = GetMax(vales); + + // + return maxVale; + } + + // + // Protected ... +protected: + // + X121ProviderInputs mInputs; + + // + // Support and Resistances ... + + // + // Check has Enough Support and Resistance ... + bool HasEnoughSupportAndResistance() + { + // + bool result = false; + + // + if (mNumberOfSRVerified <= 0 || + mMinRequiredSupportAndResistances <= 0) + { + result = true; + } + else + { + // + int currentSRsCount = CountSupportResistances(); + result = currentSRsCount >= mMinRequiredSupportAndResistances; + } + + // + return result; + } + + // + // Update Bar Index base Support and Resistances .... + void UpdateSupportsAndResistances( + int barIndex = 0 // + ) + { + // + if (mNumberOfSRVerified <= 0 || + mMinRequiredSupportAndResistances <= 0) + { + return; + } + + // + int before = CountSupportResistances(); + + // + // XICH ... + + // + // Current ... + + // + if (cMarket.ich.IsSameKijunSen(barIndex, mNumberOfSRVerified)) + { + // + double selectedKijunSen = cMarket.ich.GetKijunSen(barIndex); + AddSRValue(selectedKijunSen); + } + + // + if (cMarket.ich.IsSameSenkouSpanA(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanA = cMarket.ich.GetSenkouSpanA(barIndex); + AddSRValue(selectedSenkouSpanA); + } + + // + if (cMarket.ich.IsSameSenkouSpanB(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanB = cMarket.ich.GetSenkouSpanB(barIndex); + AddSRValue(selectedSenkouSpanB); + } + + // + // Short ... + + // + if (sMarket.ich.IsSameKijunSen(barIndex, mNumberOfSRVerified)) + { + // + double selectedKijunSen = sMarket.ich.GetKijunSen(barIndex); + AddSRValue(selectedKijunSen); + } + + // + if (sMarket.ich.IsSameSenkouSpanA(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanA = sMarket.ich.GetSenkouSpanA(barIndex); + AddSRValue(selectedSenkouSpanA); + } + + // + if (sMarket.ich.IsSameSenkouSpanB(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanB = sMarket.ich.GetSenkouSpanB(barIndex); + AddSRValue(selectedSenkouSpanB); + } + + // + // Medium ... + + // + if (mMarket.ich.IsSameKijunSen(barIndex, mNumberOfSRVerified)) + { + // + double selectedKijunSen = mMarket.ich.GetKijunSen(barIndex); + AddSRValue(selectedKijunSen); + } + + // + if (mMarket.ich.IsSameSenkouSpanA(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanA = mMarket.ich.GetSenkouSpanA(barIndex); + AddSRValue(selectedSenkouSpanA); + } + + // + if (mMarket.ich.IsSameSenkouSpanB(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanB = mMarket.ich.GetSenkouSpanB(barIndex); + AddSRValue(selectedSenkouSpanB); + } + + // + // Long ... + + // + if (lMarket.ich.IsSameKijunSen(barIndex, mNumberOfSRVerified)) + { + // + double selectedKijunSen = lMarket.ich.GetKijunSen(barIndex); + AddSRValue(selectedKijunSen); + } + + // + if (lMarket.ich.IsSameSenkouSpanA(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanA = lMarket.ich.GetSenkouSpanA(barIndex); + AddSRValue(selectedSenkouSpanA); + } + + // + if (lMarket.ich.IsSameSenkouSpanB(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanB = lMarket.ich.GetSenkouSpanB(barIndex); + AddSRValue(selectedSenkouSpanB); + } + + // + // Hind ... + + // + if (hMarket.ich.IsSameKijunSen(barIndex, mNumberOfSRVerified)) + { + // + double selectedKijunSen = hMarket.ich.GetKijunSen(barIndex); + AddSRValue(selectedKijunSen); + } + + // + if (hMarket.ich.IsSameSenkouSpanA(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanA = hMarket.ich.GetSenkouSpanA(barIndex); + AddSRValue(selectedSenkouSpanA); + } + + // + if (hMarket.ich.IsSameSenkouSpanB(barIndex, mNumberOfSRVerified)) + { + // + double selectedSenkouSpanB = hMarket.ich.GetSenkouSpanB(barIndex); + AddSRValue(selectedSenkouSpanB); + } + + // + // XDON ... + + // + // Short Market ... + + // + if (sMarket.don.IsSameUpperO(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperO = sMarket.don.GetUpperO(barIndex); + AddSRValue(selectedUpperO); + } + + // + if (sMarket.don.IsSameLowerO(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerO = sMarket.don.GetLowerO(barIndex); + AddSRValue(selectedLowerO); + } + + // + if (sMarket.don.IsSameUpperC(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperC = sMarket.don.GetUpperC(barIndex); + AddSRValue(selectedUpperC); + } + + // + if (sMarket.don.IsSameLowerC(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerC = sMarket.don.GetLowerC(barIndex); + AddSRValue(selectedLowerC); + } + + // + if (sMarket.don.IsSameUpperH(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperH = sMarket.don.GetUpperH(barIndex); + AddSRValue(selectedUpperH); + } + + // + if (sMarket.don.IsSameLowerH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerH = sMarket.don.GetLowerH(barIndex); + AddSRValue(selectedLowerH); + } + + // + if (sMarket.don.IsSameUpperL(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperL = sMarket.don.GetUpperL(barIndex); + AddSRValue(selectedUpperL); + } + + // + if (sMarket.don.IsSameLowerL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerL = sMarket.don.GetLowerL(barIndex); + AddSRValue(selectedLowerL); + } + + // + // Medium Market ... + + // + if (mMarket.don.IsSameUpperO(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperO = mMarket.don.GetUpperO(barIndex); + AddSRValue(selectedUpperO); + } + + // + if (mMarket.don.IsSameLowerO(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerO = mMarket.don.GetLowerO(barIndex); + AddSRValue(selectedLowerO); + } + + // + if (mMarket.don.IsSameUpperC(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperC = mMarket.don.GetUpperC(barIndex); + AddSRValue(selectedUpperC); + } + + // + if (mMarket.don.IsSameLowerC(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerC = mMarket.don.GetLowerC(barIndex); + AddSRValue(selectedLowerC); + } + + // + if (mMarket.don.IsSameUpperH(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperH = mMarket.don.GetUpperH(barIndex); + AddSRValue(selectedUpperH); + } + + // + if (mMarket.don.IsSameLowerH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerH = mMarket.don.GetLowerH(barIndex); + AddSRValue(selectedLowerH); + } + + // + if (mMarket.don.IsSameUpperL(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperL = mMarket.don.GetUpperL(barIndex); + AddSRValue(selectedUpperL); + } + + // + if (mMarket.don.IsSameLowerL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerL = mMarket.don.GetLowerL(barIndex); + AddSRValue(selectedLowerL); + } + + // + // Long Market ... + + // + if (lMarket.don.IsSameUpperO(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperO = lMarket.don.GetUpperO(barIndex); + AddSRValue(selectedUpperO); + } + + // + if (lMarket.don.IsSameLowerO(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerO = lMarket.don.GetLowerO(barIndex); + AddSRValue(selectedLowerO); + } + + // + if (lMarket.don.IsSameUpperC(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperC = lMarket.don.GetUpperC(barIndex); + AddSRValue(selectedUpperC); + } + + // + if (lMarket.don.IsSameLowerC(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerC = lMarket.don.GetLowerC(barIndex); + AddSRValue(selectedLowerC); + } + + // + if (lMarket.don.IsSameUpperH(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperH = lMarket.don.GetUpperH(barIndex); + AddSRValue(selectedUpperH); + } + + // + if (lMarket.don.IsSameLowerH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerH = lMarket.don.GetLowerH(barIndex); + AddSRValue(selectedLowerH); + } + + // + if (lMarket.don.IsSameUpperL(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperL = lMarket.don.GetUpperL(barIndex); + AddSRValue(selectedUpperL); + } + + // + if (lMarket.don.IsSameLowerL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerL = lMarket.don.GetLowerL(barIndex); + AddSRValue(selectedLowerL); + } + + // + // Hind Market ... + + // + if (hMarket.don.IsSameUpperO(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperO = hMarket.don.GetUpperO(barIndex); + AddSRValue(selectedUpperO); + } + + // + if (hMarket.don.IsSameLowerO(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerO = hMarket.don.GetLowerO(barIndex); + AddSRValue(selectedLowerO); + } + + // + if (hMarket.don.IsSameUpperC(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperC = hMarket.don.GetUpperC(barIndex); + AddSRValue(selectedUpperC); + } + + // + if (hMarket.don.IsSameLowerC(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerC = hMarket.don.GetLowerC(barIndex); + AddSRValue(selectedLowerC); + } + + // + if (hMarket.don.IsSameUpperH(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperH = hMarket.don.GetUpperH(barIndex); + AddSRValue(selectedUpperH); + } + + // + if (hMarket.don.IsSameLowerH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerH = hMarket.don.GetLowerH(barIndex); + AddSRValue(selectedLowerH); + } + + // + if (hMarket.don.IsSameUpperL(barIndex, mNumberOfSRVerified)) + { + // + double selectedUpperL = hMarket.don.GetUpperL(barIndex); + AddSRValue(selectedUpperL); + } + + // + if (hMarket.don.IsSameLowerL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLowerL = hMarket.don.GetLowerL(barIndex); + AddSRValue(selectedLowerL); + } + + // + // XPV ... + + // + // Short Market ... + + // + if (sMarket.pv.IsSamePeak(barIndex, mNumberOfSRVerified)) + { + // + double selectedPeak = sMarket.pv.GetPeak(barIndex); + AddSRValue(selectedPeak); + } + + // + if (sMarket.pv.IsSameVale(barIndex, mNumberOfSRVerified)) + { + // + double selectedVale = sMarket.pv.GetVale(barIndex); + AddSRValue(selectedVale); + } + + // + if (sMarket.pv.IsSameFib1(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib1 = sMarket.pv.GetFib1(barIndex); + AddSRValue(selectedFib1); + } + + // + if (sMarket.pv.IsSameFib2(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib2 = sMarket.pv.GetFib2(barIndex); + AddSRValue(selectedFib2); + } + + // + if (sMarket.pv.IsSameFib3(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib3 = sMarket.pv.GetFib3(barIndex); + AddSRValue(selectedFib3); + } + + // + if (sMarket.pv.IsSameFib4(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib4 = sMarket.pv.GetFib4(barIndex); + AddSRValue(selectedFib4); + } + + // + if (sMarket.pv.IsSameFib5(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib5 = sMarket.pv.GetFib5(barIndex); + AddSRValue(selectedFib5); + } + + // + if (sMarket.pv.IsSameSCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCHH = sMarket.pv.GetSCHH(barIndex); + AddSRValue(selectedSCHH); + } + + // + if (sMarket.pv.IsSameSCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCLL = sMarket.pv.GetSCLL(barIndex); + AddSRValue(selectedSCLL); + } + + // + if (sMarket.pv.IsSameMCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCHH = sMarket.pv.GetMCHH(barIndex); + AddSRValue(selectedMCHH); + } + + // + if (sMarket.pv.IsSameMCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCLL = sMarket.pv.GetMCLL(barIndex); + AddSRValue(selectedMCLL); + } + + // + if (sMarket.pv.IsSameLCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCHH = sMarket.pv.GetLCHH(barIndex); + AddSRValue(selectedLCHH); + } + + // + if (sMarket.pv.IsSameLCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCLL = sMarket.pv.GetLCLL(barIndex); + AddSRValue(selectedLCLL); + } + + // + if (sMarket.pv.IsSameHCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCHH = sMarket.pv.GetHCHH(barIndex); + AddSRValue(selectedHCHH); + } + + // + if (sMarket.pv.IsSameHCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCLL = sMarket.pv.GetHCLL(barIndex); + AddSRValue(selectedHCLL); + } + + // + // Medium Market ... + + // + if (mMarket.pv.IsSamePeak(barIndex, mNumberOfSRVerified)) + { + // + double selectedPeak = mMarket.pv.GetPeak(barIndex); + AddSRValue(selectedPeak); + } + + // + if (mMarket.pv.IsSameVale(barIndex, mNumberOfSRVerified)) + { + // + double selectedVale = mMarket.pv.GetVale(barIndex); + AddSRValue(selectedVale); + } + + // + if (mMarket.pv.IsSameFib1(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib1 = mMarket.pv.GetFib1(barIndex); + AddSRValue(selectedFib1); + } + + // + if (mMarket.pv.IsSameFib2(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib2 = mMarket.pv.GetFib2(barIndex); + AddSRValue(selectedFib2); + } + + // + if (mMarket.pv.IsSameFib3(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib3 = mMarket.pv.GetFib3(barIndex); + AddSRValue(selectedFib3); + } + + // + if (mMarket.pv.IsSameFib4(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib4 = mMarket.pv.GetFib4(barIndex); + AddSRValue(selectedFib4); + } + + // + if (mMarket.pv.IsSameFib5(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib5 = mMarket.pv.GetFib5(barIndex); + AddSRValue(selectedFib5); + } + + // + if (mMarket.pv.IsSameSCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCHH = mMarket.pv.GetSCHH(barIndex); + AddSRValue(selectedSCHH); + } + + // + if (mMarket.pv.IsSameSCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCLL = mMarket.pv.GetSCLL(barIndex); + AddSRValue(selectedSCLL); + } + + // + if (mMarket.pv.IsSameMCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCHH = mMarket.pv.GetMCHH(barIndex); + AddSRValue(selectedMCHH); + } + + // + if (mMarket.pv.IsSameMCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCLL = mMarket.pv.GetMCLL(barIndex); + AddSRValue(selectedMCLL); + } + + // + if (mMarket.pv.IsSameLCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCHH = mMarket.pv.GetLCHH(barIndex); + AddSRValue(selectedLCHH); + } + + // + if (mMarket.pv.IsSameLCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCLL = mMarket.pv.GetLCLL(barIndex); + AddSRValue(selectedLCLL); + } + + // + if (mMarket.pv.IsSameHCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCHH = mMarket.pv.GetHCHH(barIndex); + AddSRValue(selectedHCHH); + } + + // + if (mMarket.pv.IsSameHCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCLL = mMarket.pv.GetHCLL(barIndex); + AddSRValue(selectedHCLL); + } + + // + // Long Market ... + + // + if (lMarket.pv.IsSamePeak(barIndex, mNumberOfSRVerified)) + { + // + double selectedPeak = lMarket.pv.GetPeak(barIndex); + AddSRValue(selectedPeak); + } + + // + if (lMarket.pv.IsSameVale(barIndex, mNumberOfSRVerified)) + { + // + double selectedVale = lMarket.pv.GetVale(barIndex); + AddSRValue(selectedVale); + } + + // + if (lMarket.pv.IsSameFib1(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib1 = lMarket.pv.GetFib1(barIndex); + AddSRValue(selectedFib1); + } + + // + if (lMarket.pv.IsSameFib2(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib2 = lMarket.pv.GetFib2(barIndex); + AddSRValue(selectedFib2); + } + + // + if (lMarket.pv.IsSameFib3(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib3 = lMarket.pv.GetFib3(barIndex); + AddSRValue(selectedFib3); + } + + // + if (lMarket.pv.IsSameFib4(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib4 = lMarket.pv.GetFib4(barIndex); + AddSRValue(selectedFib4); + } + + // + if (lMarket.pv.IsSameFib5(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib5 = lMarket.pv.GetFib5(barIndex); + AddSRValue(selectedFib5); + } + + // + if (lMarket.pv.IsSameSCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCHH = lMarket.pv.GetSCHH(barIndex); + AddSRValue(selectedSCHH); + } + + // + if (lMarket.pv.IsSameSCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCLL = lMarket.pv.GetSCLL(barIndex); + AddSRValue(selectedSCLL); + } + + // + if (lMarket.pv.IsSameMCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCHH = lMarket.pv.GetMCHH(barIndex); + AddSRValue(selectedMCHH); + } + + // + if (lMarket.pv.IsSameMCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCLL = lMarket.pv.GetMCLL(barIndex); + AddSRValue(selectedMCLL); + } + + // + if (lMarket.pv.IsSameLCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCHH = lMarket.pv.GetLCHH(barIndex); + AddSRValue(selectedLCHH); + } + + // + if (lMarket.pv.IsSameLCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCLL = lMarket.pv.GetLCLL(barIndex); + AddSRValue(selectedLCLL); + } + + // + if (lMarket.pv.IsSameHCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCHH = lMarket.pv.GetHCHH(barIndex); + AddSRValue(selectedHCHH); + } + + // + if (lMarket.pv.IsSameHCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCLL = lMarket.pv.GetHCLL(barIndex); + AddSRValue(selectedHCLL); + } + + // + // Hind Market ... + + // + if (hMarket.pv.IsSamePeak(barIndex, mNumberOfSRVerified)) + { + // + double selectedPeak = hMarket.pv.GetPeak(barIndex); + AddSRValue(selectedPeak); + } + + // + if (hMarket.pv.IsSameVale(barIndex, mNumberOfSRVerified)) + { + // + double selectedVale = hMarket.pv.GetVale(barIndex); + AddSRValue(selectedVale); + } + + // + if (hMarket.pv.IsSameFib1(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib1 = hMarket.pv.GetFib1(barIndex); + AddSRValue(selectedFib1); + } + + // + if (hMarket.pv.IsSameFib2(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib2 = hMarket.pv.GetFib2(barIndex); + AddSRValue(selectedFib2); + } + + // + if (hMarket.pv.IsSameFib3(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib3 = hMarket.pv.GetFib3(barIndex); + AddSRValue(selectedFib3); + } + + // + if (hMarket.pv.IsSameFib4(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib4 = hMarket.pv.GetFib4(barIndex); + AddSRValue(selectedFib4); + } + + // + if (hMarket.pv.IsSameFib5(barIndex, mNumberOfSRVerified)) + { + // + double selectedFib5 = hMarket.pv.GetFib5(barIndex); + AddSRValue(selectedFib5); + } + + // + if (hMarket.pv.IsSameSCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCHH = hMarket.pv.GetSCHH(barIndex); + AddSRValue(selectedSCHH); + } + + // + if (hMarket.pv.IsSameSCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedSCLL = hMarket.pv.GetSCLL(barIndex); + AddSRValue(selectedSCLL); + } + + // + if (hMarket.pv.IsSameMCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCHH = hMarket.pv.GetMCHH(barIndex); + AddSRValue(selectedMCHH); + } + + // + if (hMarket.pv.IsSameMCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedMCLL = hMarket.pv.GetMCLL(barIndex); + AddSRValue(selectedMCLL); + } + + // + if (hMarket.pv.IsSameLCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCHH = hMarket.pv.GetLCHH(barIndex); + AddSRValue(selectedLCHH); + } + + // + if (hMarket.pv.IsSameLCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedLCLL = hMarket.pv.GetLCLL(barIndex); + AddSRValue(selectedLCLL); + } + + // + if (hMarket.pv.IsSameHCHH(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCHH = hMarket.pv.GetHCHH(barIndex); + AddSRValue(selectedHCHH); + } + + // + if (hMarket.pv.IsSameHCLL(barIndex, mNumberOfSRVerified)) + { + // + double selectedHCLL = hMarket.pv.GetHCLL(barIndex); + AddSRValue(selectedHCLL); + } + + // + // Add Candelstick Pivots ... + + // + // XOHCL sPBar = sMarket.GetBar(barIndex + 1); + // AddSRValue(sPBar); + + // + XOHCL mPBar = mMarket.GetBar(barIndex + 1); + AddSRValue(mPBar); + + // + XOHCL lPBar = lMarket.GetBar(barIndex + 1); + AddSRValue(lPBar); + + // + XOHCL hPBar = hMarket.GetBar(barIndex + 1); + AddSRValue(hPBar); + + // + int after = CountSupportResistances(); + + // + if (after > before) + { + // + string message = "Found: " + ToString(after - before) + " new Pivot for " + GetSymbol() + " ..."; + Print(message); + } + } + + // + void FindSupportAndResistances() + { + // + bool hasEnough = HasEnoughSupportAndResistance(); + if (hasEnough) + { + // + // if (IsNewBar()) + // { + // UpdateSupportsAndResistances(); + // } + return; + } + + // + int idx = 0; + while (!HasEnoughSupportAndResistance()) + { + // + UpdateSupportsAndResistances(idx); + + // + if (HasEnoughSupportAndResistance()) + { + break; + } + + // + idx += 50; + + // + // Print("idx: " + ToString(idx) + ", Count: " + ToString(CountSupportResistances())); + Print("Pivots: " + ToString(CountSupportResistances())); + } + } + + // + void AddSRValue(double value) + { + // + if (value <= 0) + { + return; + } + + // + AddIfNotExists( + value, + mSupportResistances // + ); + } + + // + void AddSRValue(XOHCL &bar) + { + // + if (!bar.IsValid()) + { + return; + } + + // + AddSRValue(bar.open); + AddSRValue(bar.high); + AddSRValue(bar.close); + AddSRValue(bar.low); + } + + // + // Private ... +private: + // + // Props ... + + // + int mNumberOfItems; // Number of Buffer Ites Read in Conditions ... + + // + // Support and Resistance ... + + // + int mNumberOfSRVerified; // Number of Verifications for Selecting Support and Resistances ... + + // + int mMinRequiredSupportAndResistances; // Minimum Requirement Supports and Resistances ... + + // + double mSupportResistances[]; // Holds Supports and Resistances ... + + // + // Bullish and Bearish Scores ... + + // + double mBullishScore[]; + double mBearishScore[]; + + // + // Store Market Conditions Scores ... + void AddScores(X121MarketConditions &conditions) + { + // + static datetime lasrScoreAdded = NULL; + ENUM_TIMEFRAMES mPeriod = GetPeriod(); + int seconds = PeriodSeconds(mPeriod); + datetime cTime = TimeCurrent(); + int dateDiff = (int)cTime - (int)lasrScoreAdded; + bool canDo = + // + lasrScoreAdded == NULL + ? true + : dateDiff >= seconds + // + ; + if (!canDo) + { + return; + } + + // + lasrScoreAdded = cTime; + + // + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + ArraySetAsSeries(mBullishScore, false); + ArraySetAsSeries(mBearishScore, false); + + // + Add( + bullishScore, + mBullishScore // + ); + + // + Add( + bearishScore, + mBearishScore // + ); + + // + ArraySetAsSeries(mBullishScore, true); + ArraySetAsSeries(mBearishScore, true); + + // + // string scoreMSG = "Scores: \nBullihs: " + ToString(bullishScore) + "\nBearish: " + ToString(bearishScore); + // Comment(scoreMSG); + } + + // + // Find Bullish Score Averages ... + double GetBullishScoreAverage( + int start = 0, + int count = 7 // + ) + { + // + return GetAverage( + mBullishScore, + start, + count // + ); + } + + // + // Find Bullish Scores Max Value ... + double GetBullishScoreMax( + int start = 0, + int count = 71 // + ) + { + // + return GetMax( + mBullishScore, + start, + count // + ); + } + + // + // Find Bullish Scores Min Value ... + double GetBullishScoreMin( + int start = 0, + int count = 71 // + ) + { + // + return GetMin( + mBullishScore, + start, + count // + ); + } + + // + // Find Bearish Score Averages ... + double GetBearishScoreAverage( + int start = 0, + int count = 7 // + ) + { + // + return GetAverage( + mBearishScore, + start, + count // + ); + } + + // + // Find Bearish Scores Max Value ... + double GetBearishScoreMax( + int start = 0, + int count = 71 // + ) + { + // + return GetMax( + mBearishScore, + start, + count // + ); + } + + // + // Find Bearish Scores Min Value ... + double GetBearishScoreMin( + int start = 0, + int count = 71 // + ) + { + // + return GetMin( + mBearishScore, + start, + count // + ); + } + + // + bool IsScorePassedForLong() + { + // + double bullishScore = mBullishScore[0]; + double bullishScoreAVG7 = GetBullishScoreAverage(0, 7); + + // + double bearishScore = mBearishScore[0]; + double bearishScoreAVG7 = GetBearishScoreAverage(0, 7); + + // + bool result = + // + ArraySize(mBullishScore) >= 7 && + ArraySize(mBearishScore) >= 7 && + bullishScore > bearishScore && + bullishScore > mBullishScore[1] && + bullishScore > bullishScoreAVG7 && + bearishScore < bearishScoreAVG7 + // + ; + + // + return result; + } + + // + bool IsScorePassedForShort() + { + + // + double bullishScore = mBullishScore[0]; + double bullishScoreAVG7 = GetBullishScoreAverage(0, 7); + + // + double bearishScore = mBearishScore[0]; + double bearishScoreAVG7 = GetBearishScoreAverage(0, 7); + + // + bool result = + // + ArraySize(mBullishScore) >= 7 && + ArraySize(mBearishScore) >= 7 && + bearishScore > bullishScore && + bearishScore > mBearishScore[1] && + bearishScore > bearishScoreAVG7 && + bullishScore < bullishScoreAVG7 + // + ; + + // + return result; + } + + // + // Signallers ... + + // + bool mIsLongEnable; + bool mIsShortEnable; + + // + bool mIsXSPSignalProviderEnable; + bool mIsX128SignalProviderEnable; + bool mIsX92SignalProviderEnable; + bool mIsX786SignalProviderEnable; + bool mIsX121SignalProviderEnable; + bool mIsX110SignalProviderEnable; + bool mIsXTESTSignalProviderEnable; + bool mIsXTDSignalProviderEnable; + bool mIsXTAMSignalProviderEnable; + bool mIsXSISignalProviderEnable; + bool mIsXTSFISignalProviderEnable; + bool mIsXOBDLHSignalProviderEnable; + bool mIsXCHMACCSignalProviderEnable; + bool mIsXCHMAMNSignalProviderEnable; + bool mIsXCHMAMXSignalProviderEnable; + + // + // + // Detect Signal ... + bool HasSpecificSignal( + int barIndex, // Specified Bar Index ... + ENUM_POSITION_TYPE mType, // Specific Signal Type ... + string &provider, // Signal Provider ... + int &signalPusher, // Number Of Same Time Signals ... + X121MarketConditions &mConditions, // Specified Market Conition ... + double &providedSL, + double &providedTP, + double &providedR2r // + ) + { + // + bool result = false; + + // + // Validate Signal Type is Enables ... + bool isLong = IsLong(mType); + result = + (isLong && mIsLongEnable) || + (!isLong && mIsShortEnable); + if (!result) + { + return result; + } + + // + // Now we have to Filter based on Enabled Signal Providers ... + + // + // Long ... + if (isLong && mIsLongEnable) + { + // + XSignal lSignal; + + // + signalPusher = 0; + + // + bool hasXSPSignal = false; + bool hasXTESTSignal = false; + bool hasX786Signal = false; + bool hasX121Signal = false; + bool hasX110Signal = false; + bool hasX92Signal = false; + bool hasX128Signal = false; + bool hasXTDSignal = false; + bool hasXTAMSignal = false; + bool hasXSISignal = false; + bool hasXTSFISignal = false; + bool hasXOBDLHSignal = false; + bool hasXCHMACCSignal = false; + bool hasXCHMAMNSignal = false; + bool hasXCHMAMXSignal = false; + + // + // XPS ... + if (mIsXSPSignalProviderEnable) + { + // + hasXSPSignal = XSPHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXSPSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XSP); + } + + // + signalPusher++; + } + } + + // + // XTEST ... + if (mIsXTESTSignalProviderEnable) + { + // + hasXTESTSignal = XTESTHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTESTSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTEST); + } + + // + signalPusher++; + } + } + + // + // X786 ... + if (mIsX786SignalProviderEnable) + { + // + hasX786Signal = X786HasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX786Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X786); + } + + // + signalPusher++; + } + } + + // + // X121 ... + if (mIsX121SignalProviderEnable) + { + // + hasX121Signal = X121HasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX121Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X121); + } + + // + signalPusher++; + } + } + + // + // X110 ... + if (mIsX110SignalProviderEnable) + { + // + hasX110Signal = X110HasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX110Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X110); + } + + // + signalPusher++; + } + } + + // + // X92 ... + if (mIsX92SignalProviderEnable) + { + // + hasX92Signal = X92HasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX92Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X92); + } + + // + signalPusher++; + } + } + + // + // X128 ... + if (mIsX128SignalProviderEnable) + { + // + hasX128Signal = X128HasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX128Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X128); + } + + // + signalPusher++; + } + } + + // + // XTD ... + if (mIsXTDSignalProviderEnable) + { + // + hasXTDSignal = XTDHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTDSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTD); + } + + // + signalPusher++; + } + } + + // + // XTAM ... + if (mIsXTAMSignalProviderEnable) + { + // + hasXTAMSignal = XTAMHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTAMSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTAM); + } + + // + signalPusher++; + } + } + + // + // XSI ... + if (mIsXSISignalProviderEnable) + { + // + hasXSISignal = XSIHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXSISignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XSI); + } + + // + signalPusher++; + } + } + + // + // XTSFI ... + if (mIsXTSFISignalProviderEnable) + { + // + hasXTSFISignal = XTSFIHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTSFISignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTSFI); + } + + // + signalPusher++; + } + } + + // + // XOBDLH ... + if (mIsXOBDLHSignalProviderEnable) + { + // + hasXOBDLHSignal = XOBDLHHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXOBDLHSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XOBDLH); + } + + // + signalPusher++; + } + } + + // + // XCHMACC ... + if (mIsXCHMACCSignalProviderEnable) + { + // + hasXCHMACCSignal = XCHMACCHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXCHMACCSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XCHMACC); + } + + // + signalPusher++; + } + } + + // + // XCHMAMN ... + if (mIsXCHMAMNSignalProviderEnable) + { + // + hasXCHMAMNSignal = XCHMAMNHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXCHMAMNSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XCHMAMN); + } + + // + signalPusher++; + } + } + + // + // XCHMAMX ... + if (mIsXCHMAMXSignalProviderEnable) + { + // + hasXCHMAMXSignal = XCHMAMXHasSpecifiedLongSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXCHMAMXSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XCHMAMX); + } + + // + signalPusher++; + } + } + + // + result = + // + hasXSPSignal + // + || + // + hasXTESTSignal + // + || + // + hasX786Signal + // + || + // + hasX121Signal + // + || + // + hasX110Signal + // + || + // + hasX92Signal + // + || + // + hasX128Signal + // + ; + + // + if (result) + { + return result; + } + } + + // + // Short ... + if (!isLong && mIsShortEnable) + { + // + XSignal sSignal; + + // + signalPusher = 0; + + // + bool hasXSPSignal = false; + bool hasXTESTSignal = false; + bool hasX786Signal = false; + bool hasX121Signal = false; + bool hasX110Signal = false; + bool hasX92Signal = false; + bool hasX128Signal = false; + bool hasXTDSignal = false; + bool hasXTAMSignal = false; + bool hasXSISignal = false; + bool hasXTSFISignal = false; + bool hasXOBDLHSignal = false; + bool hasXCHMACCSignal = false; + bool hasXCHMAMNSignal = false; + bool hasXCHMAMXSignal = false; + + // + // XSP ... + if (mIsXSPSignalProviderEnable) + { + // + hasXSPSignal = XSPHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXSPSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XSP); + } + + // + signalPusher++; + } + } + + // + // XTEST ... + if (mIsXTESTSignalProviderEnable) + { + // + hasXTESTSignal = XTESTHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTESTSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTEST); + } + + // + signalPusher++; + } + } + + // + // X786 ... + if (mIsX786SignalProviderEnable) + { + // + hasX786Signal = X786HasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX786Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X786); + } + + // + signalPusher++; + } + } + + // + // X121 ... + if (mIsX121SignalProviderEnable) + { + // + hasX121Signal = X121HasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX121Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X121); + } + + // + signalPusher++; + } + } + + // + // X110 ... + if (mIsX110SignalProviderEnable) + { + // + hasX110Signal = X110HasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX110Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X110); + } + + // + signalPusher++; + } + } + + // + // X92 ... + if (mIsX92SignalProviderEnable) + { + // + hasX92Signal = X92HasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX92Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X92); + } + + // + signalPusher++; + } + } + + // + // X128 ... + if (mIsX128SignalProviderEnable) + { + // + hasX128Signal = X128HasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasX128Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X128); + } + + // + signalPusher++; + } + } + + // + // XTD ... + if (mIsXTDSignalProviderEnable) + { + // + hasXTDSignal = XTDHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTDSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTD); + } + + // + signalPusher++; + } + } + + // + // XTAM ... + if (mIsXTAMSignalProviderEnable) + { + // + hasXTAMSignal = XTAMHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTAMSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTAM); + } + + // + signalPusher++; + } + } + + // + // XSI ... + if (mIsXSISignalProviderEnable) + { + // + hasXSISignal = XSIHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXSISignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XSI); + } + + // + signalPusher++; + } + } + + // + // XTSFI ... + if (mIsXTSFISignalProviderEnable) + { + // + hasXTSFISignal = XTSFIHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXTSFISignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTSFI); + } + + // + signalPusher++; + } + } + + // + // XOBDLH ... + if (mIsXOBDLHSignalProviderEnable) + { + // + hasXOBDLHSignal = XOBDLHHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXOBDLHSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XOBDLH); + } + + // + signalPusher++; + } + } + + // + // XCHMACC ... + if (mIsXCHMACCSignalProviderEnable) + { + // + hasXCHMACCSignal = XCHMACCHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXCHMACCSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XCHMACC); + } + + // + signalPusher++; + } + } + + // + // XCHMAMN ... + if (mIsXCHMAMNSignalProviderEnable) + { + // + hasXCHMAMNSignal = XCHMAMNHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXCHMAMNSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XCHMAMN); + } + + // + signalPusher++; + } + } + + // + // XCHMAMX ... + if (mIsXCHMAMXSignalProviderEnable) + { + // + hasXCHMAMXSignal = XCHMAMXHasSpecifiedShortSignal( + mConditions, + providedSL, + providedTP, + providedR2r // + ); + + // + if (hasXCHMAMXSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XCHMAMX); + } + + // + signalPusher++; + } + } + + // + result = + // + hasXSPSignal + // + || + // + hasXTESTSignal + // + || + // + hasX786Signal + // + || + // + hasX121Signal + // + || + // + hasX110Signal + // + || + // + hasX92Signal + // + || + // + hasX128Signal + // + || + // + hasXTDSignal + // + || + // + hasXTAMSignal + // + || + // + hasXSISignal + // + || + // + hasXTSFISignal + // + || + // + hasXOBDLHSignal + // + || + // + hasXCHMACCSignal + // + || + // + hasXCHMAMNSignal + // + || + // + hasXCHMAMXSignal + // + ; + + // + if (result) + { + return result; + } + } + + // + return result; + } + + // + void CalculateConditions( + X121MarketConditions &mConditions, // Market Conditions Result + int barIndex = 0 // Specified Bar Index + ) + { + // + mConditions.Clear(); + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (barIndex >= CountBars()) + { + barIndex = CountBars() + 2; + } + + // + int curr = barIndex + 1; + int prev = curr + 1; + int mLength = 10; + int mFrom = curr + mLength; + + // + mConditions.symbol = GetSymbol(); + mConditions.period = GetPeriod(); + mConditions.time = iTime( + mConditions.symbol, + mConditions.period, + barIndex // + ); + + // + GetBars( + mConditions.bars, + mConditions.symbol, + mConditions.period, + barIndex, + mNumberOfItems // + ); + + // + // Current Market Specified ... + + // + // XTM ... + tmHelper.CopyMain( + barIndex, + mNumberOfItems, + mConditions.tms); + // + mConditions.isXTMPeak = IsIncreasing( + mFrom, + curr, + mConditions.tms); + + // + mConditions.isXTMVale = IsDecreasing( + mFrom, + curr, + mConditions.tms); + + // + mConditions.isXTMBullish = mConditions.bars[curr].low > mConditions.tms[curr]; + bool isXTMBullishPrev = mConditions.bars[prev].low > mConditions.tms[prev]; + + // + mConditions.isXTMBearish = mConditions.bars[curr].high < mConditions.tms[curr]; + bool isXTMBearishPrev = mConditions.bars[prev].high < mConditions.tms[prev]; + + // + mConditions.isXTMNeutural = !mConditions.isXTMBullish && !mConditions.isXTMBearish; + bool isXTMNeuturalPrev = !isXTMBullishPrev && !isXTMBearishPrev; + + // + mConditions.isXTMEndBullish = + // + !mConditions.isXTMBullish && + isXTMBullishPrev + // + ; + + // + mConditions.isXTMEndBearish = + // + !mConditions.isXTMBearish && + isXTMBearishPrev + // + ; + + // + mConditions.isXTMStartBullish = + // + mConditions.isXTMBullish && + !isXTMBullishPrev + // + ; + + // + mConditions.isXTMStartBearish = + // + mConditions.isXTMBearish && + !isXTMBearishPrev + // + ; + + // + mConditions.isXTMEndBullishByNeutural = + // + mConditions.isXTMNeutural && + isXTMBullishPrev + // + ; + + // + mConditions.isXTMEndBearishByNeutural = + // + mConditions.isXTMNeutural && + isXTMBearishPrev + // + ; + + // + mConditions.isXTMStartBullishAfterNeutural = + // + mConditions.isXTMBullish && + isXTMNeuturalPrev + // + ; + + // + mConditions.isXTMStartBearishAfterNeutural = + // + mConditions.isXTMBearish && + isXTMNeuturalPrev + // + ; + + // + // XAMA ... + amaHelper.CopyMain( + barIndex, + mNumberOfItems, + mConditions.amas); + + // + mConditions.isXAMAPeak = IsIncreasing( + mFrom, + curr, + mConditions.amas); + + // + mConditions.isXAMAVale = IsDecreasing( + mFrom, + curr, + mConditions.amas); + + // + mConditions.isXAMABullish = mConditions.bars[curr].low > mConditions.amas[curr]; + bool isXAMABullishPrev = mConditions.bars[prev].low > mConditions.amas[prev]; + + // + mConditions.isXAMABearish = mConditions.bars[curr].high < mConditions.amas[curr]; + bool isXAMABearishPrev = mConditions.bars[prev].high < mConditions.amas[prev]; + + // + mConditions.isXAMANeutural = !mConditions.isXAMABullish && !mConditions.isXAMABearish; + bool isXAMANeuturalPrev = !isXAMABullishPrev && !isXAMABearishPrev; + + // + mConditions.isXAMAEndBullish = + // + !mConditions.isXAMABullish && + isXAMABullishPrev + // + ; + + // + mConditions.isXAMAEndBearish = + // + !mConditions.isXAMABearish && + isXAMABearishPrev + // + ; + + // + mConditions.isXAMAStartBullish = + // + mConditions.isXAMABullish && + !isXAMABullishPrev + // + ; + + // + mConditions.isXAMAStartBearish = + // + mConditions.isXAMABearish && + !isXAMABearishPrev + // + ; + + // + mConditions.isXAMAEndBullishByNeutural = + // + mConditions.isXAMANeutural && + isXAMABullishPrev + // + ; + + // + mConditions.isXAMAEndBearishByNeutural = + // + mConditions.isXAMANeutural && + isXAMABearishPrev + // + ; + + // + mConditions.isXAMAStartBullishAfterNeutural = + // + mConditions.isXAMABullish && + isXAMANeuturalPrev + // + ; + + // + mConditions.isXAMAStartBearishAfterNeutural = + // + mConditions.isXAMABearish && + isXAMANeuturalPrev + // + ; + + // + // XFI ... + fiHelper.CopyMain( + barIndex, + mNumberOfItems, + mConditions.fis); + + // + mConditions.isXFIPeak = IsIncreasing( + mFrom, + curr, + mConditions.fis); + + // + mConditions.isXFIVale = IsDecreasing( + mFrom, + curr, + mConditions.fis); + + // + mConditions.isXFIOverZero = mConditions.fis[curr] > 0; + + // + mConditions.isXFICrossedOverZero = + // + mConditions.isXFIOverZero && + mConditions.fis[prev] <= 0 + // + ; + + // + mConditions.isXFIUnderZero = mConditions.fis[curr] < 0; + + // + mConditions.isXFICrossedUnderZero = + // + mConditions.isXFIUnderZero && + mConditions.fis[prev] >= 0 + // + ; + + // + // XOBD ... + obdHelper.CopyMain( + barIndex, + mNumberOfItems, + mConditions.obds); + + // + mConditions.isXOBDSwingLow = mConditions.obds[curr] == X_SWING_LOW; + mConditions.isXOBDSwingHigh = mConditions.obds[curr] == X_SWING_HIGH; + + // + // XRSI ... + rsiHelper.CopyMain( + barIndex, + mNumberOfItems, + mConditions.rsis); + + // + double shortEntryValue = mInputs.rsiInputs.shortEntryValue; + double shortExitValue = mInputs.rsiInputs.shortExitValue; + double longEntryValue = mInputs.rsiInputs.longEntryValue; + double longExitValue = mInputs.rsiInputs.longExitValue; + + // + mConditions.isXRSIPeak = IsIncreasing( + mFrom, + curr, + mConditions.rsis); + + // + mConditions.isXRSIVale = IsDecreasing( + mFrom, + curr, + mConditions.rsis); + + // + mConditions.isXRSICrossedOverLongExit = + // + mConditions.rsis[curr] > longExitValue && + mConditions.rsis[prev] <= longExitValue; + // + ; + + // + mConditions.isXRSICrossedOverLongEntry = + // + mConditions.rsis[curr] > longEntryValue && + mConditions.rsis[prev] <= longEntryValue; + // + ; + + // + mConditions.isXRSICrossedUnderShortExit = + // + mConditions.rsis[curr] < shortExitValue && + mConditions.rsis[prev] >= shortExitValue; + // + ; + + // + mConditions.isXRSICrossedUnderShortEntry = + // + mConditions.rsis[curr] < shortEntryValue && + mConditions.rsis[prev] >= shortEntryValue; + // + ; + + // + // XLH ... + + // + // HH ... + lhHelper.CopyHH( + barIndex, + mNumberOfItems, + mConditions.lhHhs); + + // + // LL ... + lhHelper.CopyLL( + barIndex, + mNumberOfItems, + mConditions.lhLls); + + // + // Signal ... + lhHelper.CopySignal( + barIndex, + mNumberOfItems, + mConditions.lhSignals); + + // + mConditions.isXLHHHIncreased = IsIncreasing( + mFrom, + curr, + mConditions.lhHhs); + + // + mConditions.isXLHHHDecreased = IsDecreasing( + mFrom, + curr, + mConditions.lhHhs); + + // + mConditions.isXLHLLIncreased = IsIncreasing( + mFrom, + curr, + mConditions.lhLls); + + // + mConditions.isXLHLLDecreased = IsDecreasing( + mFrom, + curr, + mConditions.lhLls); + + // + mConditions.isXLHLowAttachedLL = mConditions.bars[curr].low == mConditions.lhLls[curr]; + + // + mConditions.isXLHHighAttachedHH = mConditions.bars[curr].high == mConditions.lhHhs[curr]; + ; + + // + mConditions.isXLHHHSameInLength = IsSame(mConditions.lhHhs); + + // + mConditions.isXLHLLSameInLength = IsSame(mConditions.lhLls); + + // + mConditions.isXLHPriceOverSignal = mConditions.bars[curr].low > mConditions.lhSignals[curr]; + + // + mConditions.isXLHPriceUnderSignal = mConditions.bars[curr].high < mConditions.lhSignals[curr]; + + // + mConditions.isXLHPriceInSignalRange = !mConditions.isXLHPriceOverSignal && !mConditions.isXLHPriceUnderSignal; + + // + mConditions.isXLHPriceCrossedOverSignal = + // + mConditions.isXLHPriceOverSignal && + !(mConditions.bars[prev].low > mConditions.lhSignals[prev]) + // + ; + + // + mConditions.isXLHPriceCrossedUnderSignal = + // + mConditions.isXLHPriceUnderSignal && + !(mConditions.bars[curr].high < mConditions.lhSignals[curr]) + // + ; + + // + // XTD ... + + // + // Bullish ... + tdHelper.CopyBullish( + barIndex, + mNumberOfItems, + mConditions.tdBullishs); + + // + // Bearish ... + tdHelper.CopyBearish( + barIndex, + mNumberOfItems, + mConditions.tdBearishs); + + // + // Signal ... + tdHelper.CopySignal( + barIndex, + mNumberOfItems, + mConditions.tdSignals); + + // + mConditions.isXTDSignalPeak = IsIncreasing( + mFrom, + curr, + mConditions.tdSignals); + + // + mConditions.isXTDSignalVale = IsDecreasing( + mFrom, + curr, + mConditions.tdSignals); + + // + mConditions.isXTDBullishPeak = IsIncreasing( + mFrom, + curr, + mConditions.tdBullishs); + + // + mConditions.isXTDBullishVale = IsDecreasing( + mFrom, + curr, + mConditions.tdBullishs); + + // + mConditions.isXTDBearishPeak = IsIncreasing( + mFrom, + curr, + mConditions.tdBearishs); + + // + mConditions.isXTDBearishVale = IsDecreasing( + mFrom, + curr, + mConditions.tdBearishs); + + // + mConditions.isXTDBullOverBear = mConditions.tdBullishs[curr] > mConditions.tdBearishs[curr]; + bool isXTDBullOverBearPrev = mConditions.tdBullishs[prev] > mConditions.tdBearishs[prev]; + + // + mConditions.isXTDBullUnderBear = mConditions.tdBullishs[curr] < mConditions.tdBearishs[curr]; + bool isXTDBullUnderBearPrev = mConditions.tdBullishs[prev] < mConditions.tdBearishs[prev]; + + // + mConditions.isXTDSignalOverBear = mConditions.tdSignals[curr] > mConditions.tdBearishs[curr]; + bool isXTDSignalOverBearPrev = mConditions.tdSignals[prev] > mConditions.tdBearishs[prev]; + + // + mConditions.isXTDSignalUnderBear = mConditions.tdSignals[curr] < mConditions.tdBearishs[curr]; + bool isXTDSignalUnderBearPrev = mConditions.tdSignals[prev] < mConditions.tdBearishs[prev]; + + // + mConditions.isXTDBullCrossedOverBear = + mConditions.isXTDBullOverBear && + !isXTDBullOverBearPrev; + + // + mConditions.isXTDBullCrossedUnderBear = + mConditions.isXTDBullUnderBear && + !isXTDBullUnderBearPrev; + + // + mConditions.isXTDSignalCrossedOverBear = + mConditions.isXTDSignalOverBear && + !isXTDSignalOverBearPrev; + + // + mConditions.isXTDSignalCrossedUnderBear = + mConditions.isXTDSignalUnderBear && + !isXTDSignalUnderBearPrev; + + // + // XTS ... + + // + // Current ... + tsHelper.CopyCurrent( + barIndex, + mNumberOfItems, + mConditions.tsCurrents); + + // + // Nearest ... + tsHelper.CopyNearest( + barIndex, + mNumberOfItems, + mConditions.tsNearests); + + // + // Mediest ... + tsHelper.CopyMediest( + barIndex, + mNumberOfItems, + mConditions.tsMediests); + + // + // Farest ... + tsHelper.CopyFarest( + barIndex, + mNumberOfItems, + mConditions.tsFarests); + + // + double current = mConditions.tsCurrents[curr]; + double currentPrev = mConditions.tsCurrents[prev]; + + // + double nearest = mConditions.tsNearests[curr]; + double nearestPrev = mConditions.tsNearests[prev]; + + // + double mediest = mConditions.tsMediests[curr]; + double mediestPrev = mConditions.tsMediests[prev]; + + // + double farest = mConditions.tsFarests[curr]; + double farestPrev = mConditions.tsFarests[prev]; + + // + double tsValues[] = {current, nearest, mediest, farest}; + double tsMax = GetMax(tsValues); + double tsMin = GetMin(tsValues); + + // + double tsPrevValues[] = {currentPrev, nearestPrev, mediestPrev, farestPrev}; + double tsPrevMax = GetMax(tsPrevValues); + double tsPrevMin = GetMin(tsPrevValues); + + // + mConditions.isXTSAllSame = + // + current == nearest && + nearest == mediest && + mediest == farest + // + ; + + // + mConditions.isXTSCurrentMin = current == tsMin; + mConditions.isXTSCurrentMax = current == tsMax; + + // + mConditions.isXTSCurrentOverFarest = current > farest; + bool isXTSCurrentOverFarestPrev = currentPrev > farestPrev; + + // + mConditions.isXTSCurrentOverNearest = current > nearest; + bool isXTSCurrentOverNearestPrev = currentPrev > nearestPrev; + + // + mConditions.isXTSCurrentOverMediest = current > mediest; + bool isXTSCurrentOverMediestPrev = currentPrev > mediestPrev; + + // + mConditions.isXTSCurrentUnderFarest = current < farest; + bool isXTSCurrentUnderFarestPrev = currentPrev < farestPrev; + + // + mConditions.isXTSCurrentUnderNearest = current < nearest; + bool isXTSCurrentUnderNearestPrev = currentPrev < nearestPrev; + + // + mConditions.isXTSCurrentUnderMediest = current < mediest; + bool isXTSCurrentUnderMediestPrev = currentPrev < mediestPrev; + + // + mConditions.isXTSCurrentCrossedOverFarest = + mConditions.isXTSCurrentOverFarest && + !isXTSCurrentOverFarestPrev; + + // + mConditions.isXTSCurrentCrossedOverNearest = + mConditions.isXTSCurrentOverNearest && + !isXTSCurrentOverNearestPrev; + + // + mConditions.isXTSCurrentCrossedOverMediest = + mConditions.isXTSCurrentOverMediest && + !isXTSCurrentOverMediestPrev; + + // + mConditions.isXTSCurrentCrossedUnderFarest = + mConditions.isXTSCurrentUnderFarest && + !isXTSCurrentUnderFarestPrev; + + // + mConditions.isXTSCurrentCrossedUnderNearest = + mConditions.isXTSCurrentUnderNearest && + !isXTSCurrentUnderNearestPrev; + + // + mConditions.isXTSCurrentCrossedUnderMediest = + mConditions.isXTSCurrentUnderMediest && + !isXTSCurrentUnderMediestPrev; + + // + // XCHMA ... + + // + // Short ... + + // + // Fast ... + chmaHelper.CopySCFast( + barIndex, + mNumberOfItems, + mConditions.chmaScFasts); + + // + // Slow ... + chmaHelper.CopySCSlow( + barIndex, + mNumberOfItems, + mConditions.chmaScSlows); + + // + // Medium ... + + // + // Fast ... + chmaHelper.CopyMCFast( + barIndex, + mNumberOfItems, + mConditions.chmaMcFasts); + + // + // Slow ... + chmaHelper.CopyMCSlow( + barIndex, + mNumberOfItems, + mConditions.chmaMcSlows); + + // + // Long ... + + // + // Fast ... + chmaHelper.CopyLCFast( + barIndex, + mNumberOfItems, + mConditions.chmaLcFasts); + + // + // Slow ... + chmaHelper.CopyLCSlow( + barIndex, + mNumberOfItems, + mConditions.chmaLcSlows); + + // + // Hot States ... + chmaHelper.CopyHotState( + barIndex, + mNumberOfItems, + mConditions.chmaHotStates); + + // + double scFast = mConditions.chmaScFasts[curr]; + double scSlow = mConditions.chmaScSlows[curr]; + double scFastPrev = mConditions.chmaScFasts[prev]; + double scSlowPrev = mConditions.chmaScSlows[prev]; + + // + double mcFast = mConditions.chmaMcFasts[curr]; + double mcSlow = mConditions.chmaMcSlows[curr]; + double mcFastPrev = mConditions.chmaMcFasts[prev]; + double mcSlowPrev = mConditions.chmaMcSlows[prev]; + + // + double lcFast = mConditions.chmaLcFasts[curr]; + double lcSlow = mConditions.chmaLcSlows[curr]; + double lcFastPrev = mConditions.chmaLcFasts[prev]; + double lcSlowPrev = mConditions.chmaLcSlows[prev]; + + // + double chmaValues[] = { + scFast, + scSlow, + mcFast, + mcSlow, + lcFast, + lcSlow}; + double chmaNonSCValues[] = { + mcFast, + mcSlow, + lcFast, + lcSlow}; + double chmaMin = GetMin(chmaValues); + double chmaMax = GetMax(chmaValues); + double chmaNonSCMin = GetMin(chmaNonSCValues); + double chmaNonSCMax = GetMax(chmaNonSCValues); + + // + double chmaValuesPrev[] = { + scFastPrev, + scSlowPrev, + mcFastPrev, + mcSlowPrev, + lcFastPrev, + lcSlowPrev}; + double chmaNonSCValuesPrev[] = { + mcFastPrev, + mcSlowPrev, + lcFastPrev, + lcSlowPrev}; + double chmaMinPrev = GetMin(chmaValuesPrev); + double chmaMaxPrev = GetMax(chmaValuesPrev); + double chmaNonSCMinPrev = GetMin(chmaNonSCValuesPrev); + double chmaNonSCMaxPrev = GetMax(chmaNonSCValuesPrev); + + // + mConditions.isXCHMASCOverMax = MathMin(scFast, scSlow) > chmaNonSCMax; + bool isXCHMASCOverMaxPrev = MathMin(scFastPrev, scSlowPrev) > chmaNonSCMaxPrev; + + // + mConditions.isXCHMASCOverMin = MathMin(scFast, scSlow) > chmaNonSCMin; + bool isXCHMASCOverMinPrev = MathMin(scFastPrev, scSlowPrev) > chmaNonSCMinPrev; + + // + mConditions.isXCHMASCUnderMax = MathMax(scFast, scSlow) < chmaNonSCMax; + bool isXCHMASCUnderMaxPrev = MathMax(scFastPrev, scSlowPrev) < chmaNonSCMaxPrev; + + // + mConditions.isXCHMASCUnderMin = MathMax(scFast, scSlow) < chmaNonSCMin; + bool isXCHMASCUnderMinPrev = MathMax(scFastPrev, scSlowPrev) < chmaNonSCMinPrev; + + // + mConditions.isXCHMASCCrossedOverMax = + mConditions.isXCHMASCOverMax && + !isXCHMASCOverMaxPrev; + + // + mConditions.isXCHMASCCrossedUnderMax = + mConditions.isXCHMASCUnderMax && + !isXCHMASCUnderMaxPrev; + + // + mConditions.isXCHMASCCrossedOverMin = + mConditions.isXCHMASCOverMin && + !isXCHMASCOverMinPrev; + + // + mConditions.isXCHMASCCrossedUnderMin = + mConditions.isXCHMASCUnderMin && + !isXCHMASCUnderMinPrev; + + // + // Short ... + + // + mConditions.isXCHMASCPeak = IsIncreasing( + mFrom, + curr, + mConditions.chmaScFasts); + + // + mConditions.isXCHMASCVale = IsDecreasing( + mFrom, + curr, + mConditions.chmaScFasts); + + // + mConditions.isXCHMASCTrendsUp = IsTrendingUp( + mConditions.chmaScFasts, + mConditions.chmaScSlows); + + // + mConditions.isXCHMASCTrendsDown = IsTrendingDown( + mConditions.chmaScFasts, + mConditions.chmaScSlows); + + // + mConditions.isXCHMASCFastOverSlow = scFast > scSlow; + bool isXCHMASCFastOverSlowPrev = scFastPrev > scSlowPrev; + + // + mConditions.isXCHMASCFastUnderSlow = scFast < scSlow; + bool isXCHMASCFastUnderSlowPrev = scFastPrev < scSlowPrev; + + // + mConditions.isXCHMASCFastCrossedOverSlow = + mConditions.isXCHMASCFastOverSlow && + !isXCHMASCFastOverSlowPrev; + + // + mConditions.isXCHMASCFastCrossedUnderSlow = + mConditions.isXCHMASCFastUnderSlow && + !isXCHMASCFastUnderSlowPrev; + + // + // Medium ... + + // + mConditions.isXCHMAMCPeak = IsIncreasing( + mFrom, + curr, + mConditions.chmaMcFasts); + + // + mConditions.isXCHMAMCVale = IsDecreasing( + mFrom, + curr, + mConditions.chmaMcFasts); + + // + mConditions.isXCHMAMCTrendsUp = IsTrendingUp( + mConditions.chmaMcFasts, + mConditions.chmaMcSlows); + + // + mConditions.isXCHMAMCTrendsDown = IsTrendingDown( + mConditions.chmaMcFasts, + mConditions.chmaMcSlows); + + // + mConditions.isXCHMAMCFastOverSlow = mcFast > mcSlow; + bool isXCHMAMCFastOverSlowPrev = mcFastPrev > mcSlowPrev; + + // + mConditions.isXCHMAMCFastUnderSlow = mcFast < mcSlow; + bool isXCHMAMCFastUnderSlowPrev = mcFastPrev < mcSlowPrev; + + // + mConditions.isXCHMAMCFastCrossedOverSlow = + mConditions.isXCHMAMCFastOverSlow && + !isXCHMAMCFastOverSlowPrev; + + // + mConditions.isXCHMAMCFastCrossedUnderSlow = + mConditions.isXCHMAMCFastUnderSlow && + !isXCHMAMCFastUnderSlowPrev; + + // + // Long ... + + // + mConditions.isXCHMALCPeak = IsIncreasing( + mFrom, + curr, + mConditions.chmaLcFasts); + + // + mConditions.isXCHMALCVale = IsDecreasing( + mFrom, + curr, + mConditions.chmaLcFasts); + + // + mConditions.isXCHMALCTrendsUp = IsTrendingUp( + mConditions.chmaLcFasts, + mConditions.chmaLcSlows); + + // + mConditions.isXCHMALCTrendsDown = IsTrendingDown( + mConditions.chmaMcFasts, + mConditions.chmaMcSlows); + + // + mConditions.isXCHMALCFastOverSlow = lcFast > lcSlow; + bool isXCHMALCFastOverSlowPrev = lcFastPrev > lcSlowPrev; + + // + mConditions.isXCHMALCFastUnderSlow = lcFast < lcSlow; + bool isXCHMALCFastUnderSlowPrev = lcFastPrev < lcSlowPrev; + + // + mConditions.isXCHMALCFastCrossedOverSlow = + mConditions.isXCHMALCFastOverSlow && + !isXCHMALCFastOverSlowPrev; + + // + mConditions.isXCHMALCFastCrossedUnderSlow = + mConditions.isXCHMALCFastUnderSlow && + !isXCHMALCFastUnderSlowPrev; + + // + // XCHLH ... + + // + // Short ... + + // + // HH ... + chlhHelper.CopySCHH( + barIndex, + mNumberOfItems, + mConditions.chlhScHHs); + + // + // LL ... + chlhHelper.CopySCLL( + barIndex, + mNumberOfItems, + mConditions.chlhScLLs); + + // + // Medium ... + + // + // HH ... + chlhHelper.CopyMCHH( + barIndex, + mNumberOfItems, + mConditions.chlhMcHHs); + + // + // LL ... + chlhHelper.CopyMCLL( + barIndex, + mNumberOfItems, + mConditions.chlhMcLLs); + + // + // Long ... + + // + // HH ... + chlhHelper.CopyLCHH( + barIndex, + mNumberOfItems, + mConditions.chlhLcHHs); + + // + // LL ... + chlhHelper.CopyLCLL( + barIndex, + mNumberOfItems, + mConditions.chlhLcLLs); + + // + // Hot State ... + chlhHelper.CopyHotState( + barIndex, + mNumberOfItems, + mConditions.chlhHotStates); + + // + mConditions.isXCHLHSameHHs = + // + mConditions.chlhScHHs[curr] == mConditions.chlhMcHHs[curr] && + mConditions.chlhMcHHs[curr] == mConditions.chlhLcHHs[curr] + // + ; + + // + mConditions.isXCHLHSameLLs = + // + mConditions.chlhScLLs[curr] == mConditions.chlhMcLLs[curr] && + mConditions.chlhMcLLs[curr] == mConditions.chlhLcLLs[curr] + // + ; + + // + mConditions.isXCHLHSCMCHHSame = + // + mConditions.chlhScHHs[curr] == mConditions.chlhMcHHs[curr] + // + ; + + // + mConditions.isXCHLHSCMCLLSame = + // + mConditions.chlhScLLs[curr] == mConditions.chlhMcLLs[curr] + // + ; + + // + mConditions.isXCHLHSCLCHHSame = + // + mConditions.chlhScHHs[curr] == mConditions.chlhLcLLs[curr] + // + ; + + // + mConditions.isXCHLHSCLCLLSame = + // + mConditions.chlhScLLs[curr] == mConditions.chlhLcLLs[curr] + // + ; + + // + mConditions.isXCHLHMCLCHHSame = + // + mConditions.chlhMcHHs[curr] == mConditions.chlhLcHHs[curr] + // + ; + + // + mConditions.isXCHLHMCLCLLSame = + // + mConditions.chlhMcLLs[curr] == mConditions.chlhLcLLs[curr] + // + ; + + // + // X121 Cycles Conditions ... + + // + cMarket.GetMarketConditions( + mConditions.cMarketConditions, + barIndex, + mNumberOfItems // + ); + + // + sMarket.GetMarketConditions( + mConditions.sMarketConditions, + barIndex, + mNumberOfItems // + ); + + // + mMarket.GetMarketConditions( + mConditions.mMarketConditions, + barIndex, + mNumberOfItems // + ); + + // + lMarket.GetMarketConditions( + mConditions.lMarketConditions, + barIndex, + mNumberOfItems // + ); + + // + hMarket.GetMarketConditions( + mConditions.hMarketConditions, + barIndex, + mNumberOfItems // + ); + } + + // + // Check Market Conditions is Ready for Long Signals or not ... + bool IsReadyForLong( + X121MarketConditions &mConditions, // Market Conditions ... + bool checkXCHMAMin = true, // Force Check XCHMA Min State + bool checkXCHMAMax = true, // Force Check XCHMA Max State + bool checkXCHMACycles = true, // Force Check XCHMA Cycles State + bool checkXCHMAPeaks = true, // Force Check XCHMA Peaks State + bool checkXCHMATrendPowers = true, // Force Check XCHMA Trend Powers + bool checkXOBD = true, // Force Check XOBD State + bool checkXTS = true // Force Check XTS State + ) + { + // + bool result = true; + + // + if (checkXCHMAMin) + { + // + result = + // + // XCHMA MIN ... + !( + // + (mConditions.isXCHMASCOverMin || + mConditions.isXCHMASCCrossedOverMin) && + (mConditions.isXCHMASCUnderMin || + mConditions.isXCHMASCCrossedUnderMin) + // + ); + } + + // + if (checkXCHMAMax && result) + { + // + result = + // + // XCHMA MAX ... + !( + // + (mConditions.isXCHMASCOverMax || + mConditions.isXCHMASCCrossedOverMax) && + (mConditions.isXCHMASCUnderMax || + mConditions.isXCHMASCCrossedUnderMax) + // + ) + // + ; + } + + // + if (checkXCHMACycles && result) + { + // + result = + // + // Check XCHMA Trend Bullish ... + ( + // + // All Cycles Bullish ... + ( + // + // SC ... + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + || + // + // Two Cycle Fully Bullish ... + ( + // + // SC and MC ... + ( + // + // SC ... + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) + // + ) + // + || + // + // SC and LC ... + ( + // + // SC ... + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // LC ... + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + || + // + // MC and LC ... + ( + // + // MC ... + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMAPeaks && result) + { + // + result = + // + // XCHMA Check Peaks ... + !( + // + // All Cycles Peak ... + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) + // + || + // + ( + // + // SC MC ... + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak) + // + || + // + // SC LC ... + (mConditions.isXCHMASCPeak && + mConditions.isXCHMALCPeak) + // + || + // + // MC LC ... + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMATrendPowers && result) + { + // + result = + // + // XCHMA Check Trends Power ... + !( + // + // All Trends Down ... + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + || + // + // Twisted pairs ... + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown) + // + || + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + || + // + (mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ; + } + + // + if (checkXOBD && result) + { + // + result = + // + // XOBD Check Swings ... + !mConditions.isXOBDSwingLow + // + ; + } + + // + if (checkXTS && result) + { + result = + // + // XTS Check ... + !( + // + mConditions.isXTSCurrentMin && + // + ( + // + // All Under ... + ( + (mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest) && + (mConditions.isXTSCurrentUnderFarest || + mConditions.isXTSCurrentCrossedUnderFarest)) + // + || + // + // Pairs ... + ( + // + ((mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest)) + // + || + // + ((mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderFarest || + mConditions.isXTSCurrentCrossedUnderFarest)) + // + || + // + ((mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest) && + (mConditions.isXTSCurrentUnderFarest || + mConditions.isXTSCurrentCrossedUnderFarest)) + // + ) + // + ) + // + ) + // + ; + } + + // + return result; + } + + // + // Check Market Conditions is Ready for Short Signals or not ... + bool IsReadyForShort( + X121MarketConditions &mConditions, // Market Conditions ... + bool checkXCHMAMin = true, // Force Check XCHMA Min State + bool checkXCHMAMax = true, // Force Check XCHMA Max State + bool checkXCHMACycles = true, // Force Check XCHMA Cycles State + bool checkXCHMAVales = true, // Force Check XCHMA Vales State + bool checkXCHMATrendPowers = true, // Force Check XCHMA Trend Powers + bool checkXOBD = true, // Force Check XOBD State + bool checkXTS = true // Force Check XTS State + ) + { + // + bool result = true; + + // + if (checkXCHMAMin) + { + // + result = + // + // XCHMA MIN ... + !( + // + (mConditions.isXCHMASCOverMin || + mConditions.isXCHMASCCrossedOverMin) && + (mConditions.isXCHMASCUnderMin || + mConditions.isXCHMASCCrossedUnderMin) + // + ); + } + + // + if (checkXCHMAMax && result) + { + // + result = + // + // XCHMA MAX ... + !( + // + (mConditions.isXCHMASCOverMax || + mConditions.isXCHMASCCrossedOverMax) && + (mConditions.isXCHMASCUnderMax || + mConditions.isXCHMASCCrossedUnderMax) + // + ) + // + ; + } + + // + if (checkXCHMACycles && result) + { + // + result = + // + // Check XCHMA Trend Bullish ... + ( + // + // All Cycles Bullish ... + ( + // + // SC ... + (mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) + // + && + // + // MC ... + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) + // + && + // + // LC ... + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) + // + ) + // + || + // + // Two Cycle Fully Bullish ... + ( + // + // SC and MC ... + ( + // + // SC ... + (mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) + // + ) + // + || + // + // SC and LC ... + ( + // + // SC ... + (mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) + // + && + // + // LC ... + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) + // + ) + // + || + // + // MC and LC ... + ( + // + // MC ... + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMAVales && result) + { + // + result = + // + // XCHMA Check Vales ... + !( + // + // All Cycles Vale ... + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + || + // + ( + // + // SC MC ... + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale) + // + || + // + // SC LC ... + (mConditions.isXCHMASCVale && + mConditions.isXCHMALCVale) + // + || + // + // MC LC ... + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMATrendPowers && result) + { + // + result = + // + // XCHMA Check Trends Power ... + !( + // + // All Trends Down ... + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + || + // + // Twisted pairs ... + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown) + // + || + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + || + // + (mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ; + } + + // + if (checkXOBD && result) + { + // + result = + // + // XOBD Check Swings ... + !mConditions.isXOBDSwingHigh + // + ; + } + + // + if (checkXTS && result) + { + // + result = + // + // XTS Check ... + !( + // + mConditions.isXTSCurrentMax && + // + ( + // + // All Over ... + ( + (mConditions.isXTSCurrentOverNearest || + mConditions.isXTSCurrentCrossedOverNearest) && + (mConditions.isXTSCurrentOverMediest || + mConditions.isXTSCurrentCrossedOverMediest) && + (mConditions.isXTSCurrentOverFarest || + mConditions.isXTSCurrentCrossedOverFarest)) + // + || + // + // Pairs ... + ( + // + ((mConditions.isXTSCurrentOverNearest || + mConditions.isXTSCurrentCrossedOverNearest) && + (mConditions.isXTSCurrentOverMediest || + mConditions.isXTSCurrentCrossedOverMediest)) + // + || + // + ((mConditions.isXTSCurrentOverNearest || + mConditions.isXTSCurrentCrossedOverNearest) && + (mConditions.isXTSCurrentOverFarest || + mConditions.isXTSCurrentCrossedOverFarest)) + // + || + // + ((mConditions.isXTSCurrentOverMediest || + mConditions.isXTSCurrentCrossedOverMediest) && + (mConditions.isXTSCurrentOverFarest || + mConditions.isXTSCurrentCrossedOverFarest)) + // + ) + // + ) + // + ) + // + ; + } + + // + return result; + } + + // + // Signalling based On Signallers ... + + // + // Longs ... + + // + bool XSPHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + double bearScore = 0; + double bullScore = 0; + mConditions.GenerateScore( + bullScore, + bearScore // + ); + + // + double bullScoreAVG3 = GetBullishScoreAverage(1, 3); + double bearScoreAVG100 = GetBearishScoreAverage(1, 100); + + // + result = + // + bearScore > bullScoreAVG3 && + ( + // + (bearScore > 100 && bearScore > bullScore && bullScore > (bearScore * 0.7)) + // + || + // + (bearScore < 30 && bullScore > 150) + // + || + // + (bearScore == bearScoreAVG100) + // + ) + // + ; + + // + return result; + } + + // + bool XTESTHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + return result; + } + + // + // Use XSTR ... + bool X786HasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + // Current Market ... + double cLowerHigh = cMarket.don.GetLowerH(cIndex); + bool cHasX786 = cMarket.HasX786LongConditions(); + + // + // Short Market ... + double sLowerHigh = sMarket.don.GetLowerH(cIndex); + bool sHasX786 = sMarket.HasX786LongConditions(); + + // + // Medium Market ... + double mLowerHigh = mMarket.don.GetLowerH(cIndex); + bool mHasX786 = mMarket.HasX786LongConditions(); + + // + // Long Market ... + double lLowerHigh = lMarket.don.GetLowerH(cIndex); + bool lHasX786 = lMarket.HasX786LongConditions(); + + // + // Hind Market ... + double hLowerHigh = hMarket.don.GetLowerH(cIndex); + bool hHasX786 = hMarket.HasX786LongConditions(); + + // + result = + // + cHasX786 + // + || + // + sHasX786 + // + || + // + mHasX786 + // + || + // + lHasX786 + // + // || + // // + // hHasX786 + // + ; + + // + if (result) + { + // + if (cHasX786) + { + sl = cLowerHigh; + } + else if (sHasX786) + { + sl = sLowerHigh; + } + else if (mHasX786) + { + sl = mLowerHigh; + } + else if (lHasX786) + { + sl = lLowerHigh; + } + else if (hHasX786) + { + sl = hLowerHigh; + } + + // + r2r = 2; + } + + // + return result; + } + + // + // Use XMC ... + bool X121HasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + bool hasCMarketConditions = cMarket.HasX121LongConditions(); + + // + if (hasCMarketConditions) + { + // + XOHCL cBar = cMarket.GetBar(cIndex); + + // + r2r = 1.5; + + // + sl = cMarket.mrb.GetSlow(cIndex); + // sl = cBar.FindLowest( + // 3, + // MODE_HIGH // + // ); + } + + // + result = + // + hasCMarketConditions + // + ; + + // + if (result) + { + Print("Salam"); + } + + // + return result; + } + + // + // Use XCHE ... + bool X110HasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + bool isCCHELong = + // + (mConditions.cMarketConditions.isCHESwitchedInStrongLong && + (mConditions.sMarketConditions.isCHEInStrongLong && + mConditions.mMarketConditions.isCHEInStrongLong && + mConditions.lMarketConditions.isCHEInStrongLong && + mConditions.hMarketConditions.isCHEInStrongLong)) + // + ; + + // + bool isSCHELong = + // + (mConditions.sMarketConditions.isCHESwitchedInStrongLong && + (mConditions.cMarketConditions.isCHEInStrongLong && + mConditions.mMarketConditions.isCHEInStrongLong && + mConditions.lMarketConditions.isCHEInStrongLong && + mConditions.hMarketConditions.isCHEInStrongLong)) + // + ; + + // + bool isMCHELong = + // + (mConditions.mMarketConditions.isCHESwitchedInStrongLong && + (mConditions.cMarketConditions.isCHEInStrongLong && + mConditions.sMarketConditions.isCHEInStrongLong && + mConditions.lMarketConditions.isCHEInStrongLong && + mConditions.hMarketConditions.isCHEInStrongLong)) + // + ; + + // + bool isLCHELong = + // + (mConditions.lMarketConditions.isCHESwitchedInStrongLong && + (mConditions.cMarketConditions.isCHEInStrongLong && + mConditions.sMarketConditions.isCHEInStrongLong && + mConditions.mMarketConditions.isCHEInStrongLong && + mConditions.hMarketConditions.isCHEInStrongLong)) + // + ; + + // + bool isHCHELong = + // + (mConditions.hMarketConditions.isCHESwitchedInStrongLong && + (mConditions.cMarketConditions.isCHEInStrongLong && + mConditions.sMarketConditions.isCHEInStrongLong && + mConditions.mMarketConditions.isCHEInStrongLong && + mConditions.lMarketConditions.isCHEInStrongLong)) + // + ; + + // + result = + // + // isCCHELong + // // + // || + // // + // isSCHELong + // // + // || + // + isMCHELong + // + || + // + isLCHELong + // + || + // + isHCHELong + // + ; + + // + return result; + } + + // + // Use XHK ... + bool X92HasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + int curr = 0; + int prev = 1; + + // + bool isCSMHKSwitchedToBullish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.cMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isCSMHKBullish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBullish() && + mConditions.cMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.cMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.cMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isSSMHKSwitchedToBullish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.sMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isSSMHKBullish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBullish() && + mConditions.sMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.sMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.sMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isMSMHKSwitchedToBullish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.mMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isMSMHKBullish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBullish() && + mConditions.mMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.mMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.mMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isLSMHKSwitchedToBullish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.lMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isLSMHKBullish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBullish() && + mConditions.lMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.lMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.lMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isHSMHKSwitchedToBullish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.hMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isHSMHKBullish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBullish() && + mConditions.hMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.hMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.hMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isCSMHKLong = + // + (isCSMHKBullish || + isCSMHKSwitchedToBullish) && + isSSMHKBullish && + isMSMHKBullish && + isLSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isSSMHKLong = + // + (isSSMHKBullish || + isSSMHKSwitchedToBullish) && + isCSMHKBullish && + isMSMHKBullish && + isLSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isMSMHKLong = + // + (isMSMHKBullish || + isMSMHKSwitchedToBullish) && + isSSMHKBullish && + isCSMHKBullish && + isLSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isLSMHKLong = + // + (isLSMHKBullish || + isLSMHKSwitchedToBullish) && + isSSMHKBullish && + isCSMHKBullish && + isMSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isHSMHKLong = + // + (isHSMHKBullish || + isHSMHKSwitchedToBullish) && + isSSMHKBullish && + isCSMHKBullish && + isMSMHKBullish && + isLSMHKBullish + // + ; + + // + result = + // + // isCSMHKLong + // // + // || + // // + // isSSMHKLong + // // + // || + // + isMSMHKLong + // + || + // + isLSMHKLong + // + || + // + isHSMHKLong + // + ; + + // + return result; + } + + // + // Use XMRB ... + bool X128HasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + // Current Cycle ... + + // + bool isCMRBFastOverSlow = + // + mConditions.cMarketConditions.mrbFasts[1] > mConditions.cMarketConditions.mrbSlows[1] + // + ; + + // + bool isCMRBFastCrossedOverSlow = + // + mConditions.cMarketConditions.mrbFasts[1] > mConditions.cMarketConditions.mrbSlows[1] && + mConditions.cMarketConditions.mrbFasts[2] <= mConditions.cMarketConditions.mrbSlows[2] + // + ; + + // + bool isCMRBClosedOverFast = + // + mConditions.cMarketConditions.bars[1].close > mConditions.cMarketConditions.mrbFasts[1] + // + ; + + // + // Short Cycle ... + + // + bool isSMRBFastOverSlow = + // + mConditions.sMarketConditions.mrbFasts[1] > mConditions.sMarketConditions.mrbSlows[1] + // + ; + + // + bool isSMRBFastCrossedOverSlow = + // + mConditions.sMarketConditions.mrbFasts[1] > mConditions.sMarketConditions.mrbSlows[1] && + mConditions.sMarketConditions.mrbFasts[2] <= mConditions.sMarketConditions.mrbSlows[2] + // + ; + + // + bool isSMRBClosedOverFast = + // + mConditions.sMarketConditions.bars[1].close > mConditions.sMarketConditions.mrbFasts[1] + // + ; + + // + // Medium Cycle ... + + // + bool isMMRBFastOverSlow = + // + mConditions.mMarketConditions.mrbFasts[1] > mConditions.mMarketConditions.mrbSlows[1] + // + ; + + // + bool isMMRBFastCrossedOverSlow = + // + mConditions.mMarketConditions.mrbFasts[1] > mConditions.mMarketConditions.mrbSlows[1] && + mConditions.mMarketConditions.mrbFasts[2] <= mConditions.mMarketConditions.mrbSlows[2] + // + ; + + // + bool isMMRBClosedOverFast = + // + mConditions.mMarketConditions.bars[1].close > mConditions.mMarketConditions.mrbFasts[1] + // + ; + + // + // Long Cycle ... + + // + bool isLMRBFastOverSlow = + // + mConditions.lMarketConditions.mrbFasts[1] > mConditions.lMarketConditions.mrbSlows[1] + // + ; + + // + bool isLMRBFastCrossedOverSlow = + // + mConditions.lMarketConditions.mrbFasts[1] > mConditions.lMarketConditions.mrbSlows[1] && + mConditions.lMarketConditions.mrbFasts[2] <= mConditions.lMarketConditions.mrbSlows[2] + // + ; + + // + bool isLMRBClosedOverFast = + // + mConditions.lMarketConditions.bars[1].close > mConditions.lMarketConditions.mrbFasts[1] + // + ; + + // + // Hind Cycle ... + + // + bool isHMRBFastOverSlow = + // + mConditions.hMarketConditions.mrbFasts[1] > mConditions.hMarketConditions.mrbSlows[1] + // + ; + + // + bool isHMRBFastCrossedOverSlow = + // + mConditions.hMarketConditions.mrbFasts[1] > mConditions.hMarketConditions.mrbSlows[1] && + mConditions.hMarketConditions.mrbFasts[2] <= mConditions.hMarketConditions.mrbSlows[2] + // + ; + + // + bool isHMRBClosedOverFast = + // + mConditions.hMarketConditions.bars[1].close > mConditions.hMarketConditions.mrbFasts[1] + // + ; + + // + bool isMRBLongWeight = + // + ( + // + isCMRBFastOverSlow && + isSMRBFastOverSlow && + isMMRBFastOverSlow && + isLMRBFastOverSlow && + isHMRBFastOverSlow + // + ) + // + || + // + ( + // + isCMRBFastOverSlow && + (( + isSMRBFastOverSlow && + isMMRBFastOverSlow && + isLMRBFastOverSlow) + // + || + // + ( + isSMRBFastOverSlow && + isLMRBFastOverSlow && + isHMRBFastOverSlow) + // + || + // + ( + isMMRBFastOverSlow && + isLMRBFastOverSlow && + isHMRBFastOverSlow)) + // + ) + // + ; + + // + bool isMBRCloseLong = + // + ( + // + isCMRBClosedOverFast && + isSMRBClosedOverFast && + isMMRBClosedOverFast && + isLMRBClosedOverFast && + isHMRBClosedOverFast + // + ) + // + || + // + ( + // + isCMRBClosedOverFast && + (( + isSMRBClosedOverFast && + isMMRBClosedOverFast) + // + || + // + ( + isSMRBClosedOverFast && + isLMRBClosedOverFast) + // + || + // + ( + isSMRBClosedOverFast && + isHMRBClosedOverFast) + // + || + // + ( + isMMRBClosedOverFast && + isLMRBClosedOverFast) + // + || + // + ( + isLMRBClosedOverFast && + isHMRBClosedOverFast) + // + || + // + ( + isMMRBClosedOverFast && + isHMRBClosedOverFast) + // + || + // + ( + isSMRBClosedOverFast && + isMMRBClosedOverFast && + isLMRBClosedOverFast) + // + || + // + ( + isSMRBClosedOverFast && + isLMRBClosedOverFast && + isHMRBClosedOverFast) + // + || + // + ( + isMMRBClosedOverFast && + isLMRBClosedOverFast && + isHMRBClosedOverFast)) + // + ) + // + ; + + // + bool isCMRBShort = + // + (isCMRBFastOverSlow || + isCMRBFastCrossedOverSlow) + // + && + // + isCMRBClosedOverFast && + // + isMRBLongWeight && + // + isMBRCloseLong + // + ; + + // + bool isSMRBShort = + // + (isSMRBFastOverSlow || + isSMRBFastCrossedOverSlow) + // + && + // + isSMRBClosedOverFast && + // + isMRBLongWeight && + // + isMBRCloseLong + // + ; + + // + bool isMMRBShort = + // + (isMMRBFastOverSlow || + isMMRBFastCrossedOverSlow) + // + && + // + isMMRBClosedOverFast && + // + isMRBLongWeight && + // + isMBRCloseLong + // + ; + + // + bool isLMRBShort = + // + (isLMRBFastOverSlow || + isLMRBFastCrossedOverSlow) + // + && + // + isLMRBClosedOverFast && + // + isMRBLongWeight && + // + isMBRCloseLong + // + ; + + // + bool isHMRBShort = + // + (isHMRBFastOverSlow || + isHMRBFastCrossedOverSlow) + // + && + // + isHMRBClosedOverFast && + // + isMRBLongWeight && + // + isMBRCloseLong + // + ; + + // + result = + // + // isCMRBShort + // // + // || + // // + // isSMRBShort + // // + // || + // + isMMRBShort + // + || + // + isLMRBShort + // + || + // + isHMRBShort + // + ; + + // + return result; + } + + // + // XTD ... + bool XTDHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XTAM ... + bool XTAMHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XSI ... + bool XSIHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XTSFI ... + bool XTSFIHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XOBDLH ... + bool XOBDLHHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XCHMACC ... + bool XCHMACCHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XCHMAMN ... + bool XCHMAMNHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XCHMAMX ... + bool XCHMAMXHasSpecifiedLongSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // Short ... + + // + bool XSPHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + double bearScore = 0; + double bullScore = 0; + mConditions.GenerateScore( + bullScore, + bearScore // + ); + + // + double bearScoreAVG3 = GetBearishScoreAverage(1, 3); + double bullScoreAVG100 = GetBullishScoreAverage(1, 100); + + // + result = + // + bearScore > bearScoreAVG3 && + ( + // + (bullScore > 100 && bullScore > bearScore && bearScore > (bullScore * 0.7)) + // + || + // + (bullScore < 30 && bearScore > 150) + // + || + // + (bullScore == bullScoreAVG100) + // + ); + + // + return result; + } + + // + bool XTESTHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + return result; + } + + // + // Use XSTR ... + bool X786HasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + // Current Market ... + double cUpperLow = cMarket.don.GetUpperL(cIndex); + bool cHasX786 = cMarket.HasX786ShortConditions(); + + // + // Short Market ... + double sUpperLow = sMarket.don.GetUpperL(cIndex); + bool sHasX786 = sMarket.HasX786ShortConditions(); + + // + // Medium Market ... + double mUpperLow = mMarket.don.GetUpperL(cIndex); + bool mHasX786 = mMarket.HasX786ShortConditions(); + + // + // Long Market ... + double lUpperLow = lMarket.don.GetUpperL(cIndex); + bool lHasX786 = lMarket.HasX786ShortConditions(); + + // + // Hind Market ... + double hUpperLow = hMarket.don.GetUpperL(cIndex); + bool hHasX786 = hMarket.HasX786ShortConditions(); + + // + result = + // + cHasX786 + // + || + // + sHasX786 + // + || + // + mHasX786 + // + || + // + lHasX786 + // + // || + // // + // hHasX786 + // + ; + + // + if (result) + { + // + if (cHasX786) + { + sl = cUpperLow; + } + else if (sHasX786) + { + sl = sUpperLow; + } + else if (mHasX786) + { + sl = mUpperLow; + } + else if (lHasX786) + { + sl = lUpperLow; + } + else if (hHasX786) + { + sl = hUpperLow; + } + + // + r2r = 2; + } + + // + return result; + } + + // + // Use XMC ... + bool X121HasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + bool hasCMarketConditions = cMarket.HasX121ShortConditions(); + + // + if (hasCMarketConditions) + { + // + XOHCL cBar = cMarket.GetBar(cIndex); + + // + r2r = 1.5; + + // + sl = cBar.FindHighest( + 3, + MODE_HIGH // + ); + } + + // + result = + // + hasCMarketConditions + // + ; + + // + if (result) + { + Print("Salam"); + } + + // + return result; + } + + // + // Use XCHE ... + bool X110HasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + bool isCCHEShort = + // + (mConditions.cMarketConditions.isCHESwitchedInStrongShort && + (mConditions.sMarketConditions.isCHEInStrongShort && + mConditions.mMarketConditions.isCHEInStrongShort && + mConditions.lMarketConditions.isCHEInStrongShort && + mConditions.hMarketConditions.isCHEInStrongShort)) + // + ; + + // + bool isSCHEShort = + // + (mConditions.sMarketConditions.isCHESwitchedInStrongShort && + (mConditions.cMarketConditions.isCHEInStrongShort && + mConditions.mMarketConditions.isCHEInStrongShort && + mConditions.lMarketConditions.isCHEInStrongShort && + mConditions.hMarketConditions.isCHEInStrongShort)) + // + ; + + // + bool isMCHEShort = + // + (mConditions.mMarketConditions.isCHESwitchedInStrongShort && + (mConditions.cMarketConditions.isCHEInStrongShort && + mConditions.sMarketConditions.isCHEInStrongShort && + mConditions.lMarketConditions.isCHEInStrongShort && + mConditions.hMarketConditions.isCHEInStrongShort)) + // + ; + + // + bool isLCHEShort = + // + (mConditions.lMarketConditions.isCHESwitchedInStrongShort && + (mConditions.cMarketConditions.isCHEInStrongShort && + mConditions.sMarketConditions.isCHEInStrongShort && + mConditions.mMarketConditions.isCHEInStrongShort && + mConditions.hMarketConditions.isCHEInStrongShort)) + // + ; + + // + bool isHCHEShort = + // + (mConditions.hMarketConditions.isCHESwitchedInStrongShort && + (mConditions.cMarketConditions.isCHEInStrongShort && + mConditions.sMarketConditions.isCHEInStrongShort && + mConditions.mMarketConditions.isCHEInStrongShort && + mConditions.lMarketConditions.isCHEInStrongShort)) + // + ; + + // + result = + // + // isCCHEShort + // // + // || + // // + // isSCHEShort + // // + // || + // + isMCHEShort + // + || + // + isLCHEShort + // + || + // + isHCHEShort + // + ; + + // + return result; + } + + // + // Use XHK ... + bool X92HasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + int curr = 0; + int prev = 1; + + // + bool isCSMHKSwitchedToBearish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.cMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isCSMHKBearish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBearish() && + mConditions.cMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.cMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.cMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isSSMHKSwitchedToBearish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.sMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isSSMHKBearish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBearish() && + mConditions.sMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.sMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.sMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isMSMHKSwitchedToBearish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.mMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isMSMHKBearish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBearish() && + mConditions.mMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.mMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.mMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isLSMHKSwitchedToBearish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.lMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isLSMHKBearish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBearish() && + mConditions.lMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.lMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.lMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isHSMHKSwitchedToBearish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.hMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isHSMHKBearish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBearish() && + mConditions.hMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.hMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.hMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isCSMHKShort = + // + (isCSMHKSwitchedToBearish) && + isSSMHKBearish && + isMSMHKBearish && + isLSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isSSMHKShort = + // + (isSSMHKSwitchedToBearish) && + isCSMHKBearish && + isMSMHKBearish && + isLSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isMSMHKShort = + // + (isMSMHKSwitchedToBearish) && + isSSMHKBearish && + isCSMHKBearish && + isLSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isLSMHKShort = + // + (isLSMHKSwitchedToBearish) && + isSSMHKBearish && + isCSMHKBearish && + isMSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isHSMHKShort = + // + (isHSMHKSwitchedToBearish) && + isSSMHKBearish && + isCSMHKBearish && + isMSMHKBearish && + isLSMHKBearish + // + ; + + // + result = + // + // isCSMHKShort + // // + // || + // // + // isSSMHKShort + // // + // || + // + isMSMHKShort + // + || + // + isLSMHKShort + // + || + // + isHSMHKShort + // + ; + + // + return result; + } + + // + // Use XMRB ... + bool X128HasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + // Current Cycle ... + + // + bool isCMRBFastUnderSlow = + // + mConditions.cMarketConditions.mrbFasts[1] < mConditions.cMarketConditions.mrbSlows[1] + // + ; + + // + bool isCMRBFastCrossedUnderSlow = + // + mConditions.cMarketConditions.mrbFasts[1] < mConditions.cMarketConditions.mrbSlows[1] && + mConditions.cMarketConditions.mrbFasts[2] >= mConditions.cMarketConditions.mrbSlows[2] + // + ; + + // + bool isCMRBClosedUnderFast = + // + mConditions.cMarketConditions.bars[1].close < mConditions.cMarketConditions.mrbFasts[1] + // + ; + + // + // Short Cycle ... + + // + bool isSMRBFastUnderSlow = + // + mConditions.sMarketConditions.mrbFasts[1] < mConditions.sMarketConditions.mrbSlows[1] + // + ; + + // + bool isSMRBFastCrossedUnderSlow = + // + mConditions.sMarketConditions.mrbFasts[1] < mConditions.sMarketConditions.mrbSlows[1] && + mConditions.sMarketConditions.mrbFasts[2] >= mConditions.sMarketConditions.mrbSlows[2] + // + ; + + // + bool isSMRBClosedUnderFast = + // + mConditions.sMarketConditions.bars[1].close < mConditions.sMarketConditions.mrbFasts[1] + // + ; + + // + // Medium Cycle ... + + // + bool isMMRBFastUnderSlow = + // + mConditions.mMarketConditions.mrbFasts[1] < mConditions.mMarketConditions.mrbSlows[1] + // + ; + + // + bool isMMRBFastCrossedUnderSlow = + // + mConditions.mMarketConditions.mrbFasts[1] < mConditions.mMarketConditions.mrbSlows[1] && + mConditions.mMarketConditions.mrbFasts[2] >= mConditions.mMarketConditions.mrbSlows[2] + // + ; + + // + bool isMMRBClosedUnderFast = + // + mConditions.mMarketConditions.bars[1].close < mConditions.mMarketConditions.mrbFasts[1] + // + ; + + // + // Long Cycle ... + + // + bool isLMRBFastUnderSlow = + // + mConditions.lMarketConditions.mrbFasts[1] < mConditions.lMarketConditions.mrbSlows[1] + // + ; + + // + bool isLMRBFastCrossedUnderSlow = + // + mConditions.lMarketConditions.mrbFasts[1] < mConditions.lMarketConditions.mrbSlows[1] && + mConditions.lMarketConditions.mrbFasts[2] >= mConditions.lMarketConditions.mrbSlows[2] + // + ; + + // + bool isLMRBClosedUnderFast = + // + mConditions.lMarketConditions.bars[1].close < mConditions.lMarketConditions.mrbFasts[1] + // + ; + + // + // Hind Cycle ... + + // + bool isHMRBFastUnderSlow = + // + mConditions.hMarketConditions.mrbFasts[1] < mConditions.hMarketConditions.mrbSlows[1] + // + ; + + // + bool isHMRBFastCrossedUnderSlow = + // + mConditions.hMarketConditions.mrbFasts[1] < mConditions.hMarketConditions.mrbSlows[1] && + mConditions.hMarketConditions.mrbFasts[2] >= mConditions.hMarketConditions.mrbSlows[2] + // + ; + + // + bool isHMRBClosedUnderFast = + // + mConditions.hMarketConditions.bars[1].close < mConditions.hMarketConditions.mrbFasts[1] + // + ; + + // + bool isMRBShortWeight = + // + ( + // + isCMRBFastUnderSlow && + isSMRBFastUnderSlow && + isMMRBFastUnderSlow && + isLMRBFastUnderSlow && + isHMRBFastUnderSlow + // + ) + // + || + // + ( + // + isCMRBFastUnderSlow && + (( + isSMRBFastUnderSlow && + isMMRBFastUnderSlow && + isLMRBFastUnderSlow) + // + || + // + ( + isSMRBFastUnderSlow && + isLMRBFastUnderSlow && + isHMRBFastUnderSlow) + // + || + // + ( + isMMRBFastUnderSlow && + isLMRBFastUnderSlow && + isHMRBFastUnderSlow)) + // + ) + // + ; + + // + bool isMBRCloseShort = + // + ( + // + isCMRBClosedUnderFast && + isSMRBClosedUnderFast && + isMMRBClosedUnderFast && + isLMRBClosedUnderFast && + isHMRBClosedUnderFast + // + ) + // + || + // + ( + // + isCMRBClosedUnderFast && + (( + isSMRBClosedUnderFast && + isMMRBClosedUnderFast) + // + || + // + ( + isSMRBClosedUnderFast && + isLMRBClosedUnderFast) + // + || + // + ( + isSMRBClosedUnderFast && + isHMRBClosedUnderFast) + // + || + // + ( + isMMRBClosedUnderFast && + isLMRBClosedUnderFast) + // + || + // + ( + isLMRBClosedUnderFast && + isHMRBClosedUnderFast) + // + || + // + ( + isMMRBClosedUnderFast && + isHMRBClosedUnderFast) + // + || + // + ( + isSMRBClosedUnderFast && + isMMRBClosedUnderFast && + isLMRBClosedUnderFast) + // + || + // + ( + isSMRBClosedUnderFast && + isLMRBClosedUnderFast && + isHMRBClosedUnderFast) + // + || + // + ( + isMMRBClosedUnderFast && + isLMRBClosedUnderFast && + isHMRBClosedUnderFast)) + // + ) + // + ; + + // + bool isCMRBShort = + // + (isCMRBFastUnderSlow || + isCMRBFastCrossedUnderSlow) + // + && + // + isCMRBClosedUnderFast && + // + isMRBShortWeight && + // + isMBRCloseShort + // + ; + + // + bool isSMRBShort = + // + (isSMRBFastUnderSlow || + isSMRBFastCrossedUnderSlow) + // + && + // + isSMRBClosedUnderFast && + // + isMRBShortWeight && + // + isMBRCloseShort + // + ; + + // + bool isMMRBShort = + // + (isMMRBFastUnderSlow || + isMMRBFastCrossedUnderSlow) + // + && + // + isMMRBClosedUnderFast && + // + isMRBShortWeight && + // + isMBRCloseShort + // + ; + + // + bool isLMRBShort = + // + (isLMRBFastUnderSlow || + isLMRBFastCrossedUnderSlow) + // + && + // + isLMRBClosedUnderFast && + // + isMRBShortWeight && + // + isMBRCloseShort + // + ; + + // + bool isHMRBShort = + // + (isHMRBFastUnderSlow || + isHMRBFastCrossedUnderSlow) + // + && + // + isHMRBClosedUnderFast && + // + isMRBShortWeight && + // + isMBRCloseShort + // + ; + + // + result = + // + // isCMRBShort + // // + // || + // // + // isSMRBShort + // // + // || + // + isMMRBShort + // + || + // + isLMRBShort + // + || + // + isHMRBShort + // + ; + + // + return result; + } + + // + // XTD ... + bool XTDHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XTAM ... + bool XTAMHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XSI ... + bool XSIHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XTSFI ... + bool XTSFIHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XOBDLH ... + bool XOBDLHHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XCHMACC ... + bool XCHMACCHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XCHMAMN ... + bool XCHMAMNHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // XCHMAMX ... + bool XCHMAMXHasSpecifiedShortSignal( + X121MarketConditions &mConditions, // + double &sl, // Provided SL ... + double &tp, // Provided TP ... + double &r2r // Risk Reward Ratio ... + ) + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // Base Signals ... + // Common Conditions ... + + // + bool HasBaseLongConditions( + X121MarketConditions &mConditions, + int &pusher // + ) + { + // + bool result = false; + + // + int count = 0; + + // + bool hasXTDConditions = XTDHasLongConditions(mConditions); + if (hasXTDConditions) + { + count++; + } + bool hasXTAMConditions = XTAMHasLongConditions(mConditions); + if (hasXTAMConditions) + { + count++; + } + bool hasXSIConditions = XSIHasLongConditions(mConditions); + if (hasXSIConditions) + { + count++; + } + bool hasXTSFIConditions = XTSFIHasLongConditions(mConditions); + if (hasXTSFIConditions) + { + count++; + } + bool hasXOBDLHConditions = XOBDLHHasLongConditions(mConditions); + if (hasXOBDLHConditions) + { + count++; + } + bool hasXCHMACCConditions = XCHMACCHasLongConditions(mConditions); + if (hasXCHMACCConditions) + { + count++; + } + bool hasXCHMAMNConditions = XCHMAMNHasLongConditions(mConditions); + if (hasXCHMAMNConditions) + { + count++; + } + bool hasXCHMAMXConditions = XCHMAMXHasLongConditions(mConditions); + if (hasXCHMAMXConditions) + { + count++; + } + + // + result = count >= 1; + pusher = count; + + // + return result; + } + + // + bool HasBaseShortConditions( + X121MarketConditions &mConditions, + int &pusher // + ) + { + // + bool result = false; + + // + int count = 0; + + // + bool hasXTDConditions = XTDHasShortConditions(mConditions); + if (hasXTDConditions) + { + count++; + } + bool hasXTAMConditions = XTAMHasShortConditions(mConditions); + if (hasXTAMConditions) + { + count++; + } + bool hasXSIConditions = XSIHasShortConditions(mConditions); + if (hasXSIConditions) + { + count++; + } + bool hasXTSFIConditions = XTSFIHasShortConditions(mConditions); + if (hasXTSFIConditions) + { + count++; + } + bool hasXOBDLHConditions = XOBDLHHasShortConditions(mConditions); + if (hasXOBDLHConditions) + { + count++; + } + bool hasXCHMACCConditions = XCHMACCHasShortConditions(mConditions); + if (hasXCHMACCConditions) + { + count++; + } + bool hasXCHMAMNConditions = XCHMAMNHasShortConditions(mConditions); + if (hasXCHMAMNConditions) + { + count++; + } + bool hasXCHMAMXConditions = XCHMAMXHasShortConditions(mConditions); + if (hasXCHMAMXConditions) + { + count++; + } + + // + result = count >= 1; + pusher = count; + + // + return result; + } + + // + // XTD ... + + // + bool XTDHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXTDSignalCrossedOverBear + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong(mConditions) + // + ) + // + ; + + // + return result; + } + + // + bool XTDHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXTDSignalCrossedUnderBear + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort(mConditions) + // + ) + // + ; + + // + return result; + } + + // + // XTAM ... + + // + bool XTAMHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + (mConditions.amas[1] > mConditions.tms[1] && + mConditions.amas[2] > mConditions.tms[2]) + // + && + // + !(mConditions.amas[2] > mConditions.tms[2] && + mConditions.amas[3] > mConditions.tms[3]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong(mConditions) + // + ) + // + ; + + // + return result; + } + + // + bool XTAMHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + (mConditions.amas[1] < mConditions.amas[1] && + mConditions.amas[2] < mConditions.amas[2]) + // + && + // + !(mConditions.amas[2] < mConditions.amas[2] && + mConditions.amas[3] < mConditions.amas[3]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort(mConditions) + // + ) + // + ; + + // + return result; + } + + // + // XSI ... + + // + bool XSIHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXRSICrossedOverLongEntry && + mConditions.rsis[3] < mInputs.rsiInputs.longEntryValue + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + true, // XCHMA Cycles + true, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + bool XSIHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXRSICrossedUnderShortEntry && + mConditions.rsis[3] > mInputs.rsiInputs.shortEntryValue + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + true, // XCHMA Cycles + true, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // XTSFI ... + + // + bool XTSFIHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + double tsValues[] = { + mConditions.tsCurrents[1], + mConditions.tsNearests[1], + mConditions.tsMediests[1], + mConditions.tsFarests[1], + }; + + // + double tsMin = GetMin(tsValues); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + tsMin == mConditions.tsFarests[1] && + (mConditions.isXTSCurrentOverFarest || + mConditions.isXTSCurrentCrossedOverFarest) && + (mConditions.tsCurrents[1] < mConditions.tsNearests[1] || + mConditions.tsCurrents[1] < mConditions.tsMediests[1]) && + !(mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong(mConditions) + // + ) + // + ; + + // + return result; + } + + // + bool XTSFIHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + double tsValues[] = { + mConditions.tsCurrents[1], + mConditions.tsNearests[1], + mConditions.tsMediests[1], + mConditions.tsFarests[1], + }; + + // + double tsMax = GetMax(tsValues); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + tsMax == mConditions.tsFarests[1] && + (mConditions.isXTSCurrentUnderFarest || + mConditions.isXTSCurrentCrossedUnderFarest) && + (mConditions.tsCurrents[1] > mConditions.tsNearests[1] || + mConditions.tsCurrents[1] > mConditions.tsMediests[1]) && + !(mConditions.isXTSCurrentOverNearest || + mConditions.isXTSCurrentCrossedOverNearest) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort(mConditions) + // + ) + // + ; + + // + return result; + } + + // + // XOBDLH ... + + // + bool XOBDLHHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + X121MarketConditions mConditions2; + GetMarketConditions( + mConditions, + 2 // + ); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions2.isXOBDSwingLow && + mConditions2.isXLHLowAttachedLL && + mConditions.lhLls[1] >= mConditions.lhLls[2] + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + false, // XOBD + false // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + bool XOBDLHHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + X121MarketConditions mConditions2; + GetMarketConditions( + mConditions, + 2 // + ); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions2.isXOBDSwingHigh && + mConditions2.isXLHHighAttachedHH && + mConditions.lhHhs[1] <= mConditions.lhHhs[2] + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + false, // XOBD + false // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // XCHMACC ... + + // + bool XCHMACCHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.chmaScFasts[1] > mConditions.chmaScSlows[1] && + mConditions.chmaMcFasts[1] > mConditions.chmaMcSlows[1] && + mConditions.chmaLcFasts[1] > mConditions.chmaLcSlows[1] && + // + mConditions.chmaScFasts[2] > mConditions.chmaScSlows[2] && + mConditions.chmaMcFasts[2] > mConditions.chmaMcSlows[2] && + mConditions.chmaLcFasts[2] > mConditions.chmaLcSlows[2] && + // + !( + // + mConditions.chmaScFasts[3] > mConditions.chmaScSlows[3] && + mConditions.chmaMcFasts[3] > mConditions.chmaMcSlows[3] && + mConditions.chmaLcFasts[3] > mConditions.chmaLcSlows[3] + // + ) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong(mConditions) + // + ) + // + ; + + // + return result; + } + + // + bool XCHMACCHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.chmaScFasts[1] < mConditions.chmaScSlows[1] && + mConditions.chmaMcFasts[1] < mConditions.chmaMcSlows[1] && + mConditions.chmaLcFasts[1] < mConditions.chmaLcSlows[1] && + // + mConditions.chmaScFasts[2] < mConditions.chmaScSlows[2] && + mConditions.chmaMcFasts[2] < mConditions.chmaMcSlows[2] && + mConditions.chmaLcFasts[2] < mConditions.chmaLcSlows[2] && + // + !( + // + mConditions.chmaScFasts[3] < mConditions.chmaScSlows[3] && + mConditions.chmaMcFasts[3] < mConditions.chmaMcSlows[3] && + mConditions.chmaLcFasts[3] < mConditions.chmaLcSlows[3] + // + ) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong(mConditions) + // + ) + // + ; + + // + return result; + } + + // + // XCHMAMN ... + + // + bool XCHMAMNHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + double nonSC2[] = { + mConditions.chmaMcFasts[2], + mConditions.chmaMcSlows[2], + mConditions.chmaLcFasts[2], + mConditions.chmaLcSlows[2], + }; + + // + double nonSCMax2 = GetMax(nonSC2); + double nonSCMin2 = GetMax(nonSC2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXCHMASCCrossedOverMin && + mConditions.chmaScFasts[2] < nonSCMin2 && + mConditions.chmaScSlows[2] < nonSCMin2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + bool XCHMAMNHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + double nonSC2[] = { + mConditions.chmaMcFasts[2], + mConditions.chmaMcSlows[2], + mConditions.chmaLcFasts[2], + mConditions.chmaLcSlows[2], + }; + + // + double nonSCMax2 = GetMax(nonSC2); + double nonSCMin2 = GetMax(nonSC2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXCHMASCCrossedUnderMin && + mConditions.chmaScFasts[2] > nonSCMin2 && + mConditions.chmaScSlows[2] > nonSCMin2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + // + return result; + } + + // + // XCHMAMX ... + + // + bool XCHMAMXHasLongConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + double nonSC2[] = { + mConditions.chmaMcFasts[2], + mConditions.chmaMcSlows[2], + mConditions.chmaLcFasts[2], + mConditions.chmaLcSlows[2], + }; + + // + double nonSCMax2 = GetMax(nonSC2); + double nonSCMin2 = GetMax(nonSC2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXCHMASCCrossedOverMax && + mConditions.chmaScFasts[2] < nonSCMax2 && + mConditions.chmaScSlows[2] < nonSCMax2 && + MathAbs(nonSCMax2 - mConditions.chmaScFasts[2]) > MathAbs(mConditions.chmaScFasts[2] - mConditions.chmaScSlows[2]) && + MathAbs(nonSCMax2 - mConditions.chmaScSlows[2]) > MathAbs(mConditions.chmaScFasts[2] - mConditions.chmaScSlows[2]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + bool XCHMAMXHasShortConditions( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + double nonSC2[] = { + mConditions.chmaMcFasts[2], + mConditions.chmaMcSlows[2], + mConditions.chmaLcFasts[2], + mConditions.chmaLcSlows[2], + }; + + // + double nonSCMax2 = GetMax(nonSC2); + double nonSCMin2 = GetMax(nonSC2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mConditions.isXCHMASCCrossedUnderMax && + mConditions.chmaScFasts[2] > nonSCMax2 && + mConditions.chmaScSlows[2] > nonSCMax2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + mConditions, + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // +}; + +// +// Tools ... + +// +// Model Provider Descriptor ... +struct X121ProviderDescriptor +{ + // + string symbol; // Trading Symbol + ENUM_TIMEFRAMES period; // Trading Timeframe + double staticVolume; // Static Volume for Positions + bool allowLong; // Allow Long Signals + bool allowShort; // Allow Short Signals + ENUM_X121_SIGNAL_PROVIDERS signallers[]; // Allowed Signal Providers + + // + X121ProviderInputs inputs; + XSCX121Provider *provider; + + // + XSignal signal; + X121MarketConditions conditions; + + // + // Tools ... + + // + bool Init() + { + // + bool result = false; + + // + result = this.Init( + this.symbol, + this.period, + this.signallers, + this.allowLong, + this.allowShort, + this.staticVolume // + ); + + // + return result; + } + + // + bool Init( + ENUM_X121_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers + bool mAllowLong = true, // Allow Long Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions + ) + { + // + bool result = false; + + // + result = this.Init( + this.symbol, + this.period, + mSignallers, + mAllowLong, + mAllowShort, + mStaticVolume // + ); + + // + return result; + } + + // + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mPeriod, // Trading Timeframe + ENUM_X121_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers + bool mAllowLong = true, // Allow Long Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions + ) + { + // + bool result = false; + + // + result = + // + inputs.IsValid() && + IsValid(mSymbol) && + IsValid(mPeriod) && + NotEmpty(mStaticVolume) && + (allowLong || allowShort) && + ArraySize(mSignallers) > 0 + // + ; + if (!result) + { + return result; + } + + // + this.symbol = mSymbol; + this.period = mPeriod; + this.allowLong = mAllowLong; + this.allowShort = mAllowShort; + this.staticVolume = mStaticVolume; + + // + ENUM_X121_SIGNAL_PROVIDERS tmp[]; + Copy( + mSignallers, + tmp // + ); + Copy( + tmp, + this.signallers // + ); + + // + // Instantiate Provider ... + provider = new XSCX121Provider( + this.symbol, + this.period, + this.staticVolume // + ); + + // + // Set Long/Short State ... + + // + provider + .SetSignalTypeState( + POSITION_TYPE_BUY, + this.allowLong // + ); + + // + provider + .SetSignalTypeState( + POSITION_TYPE_SELL, + this.allowShort // + ); + + // + // Enable Required Signallers ... + provider + .SetSignalProviderStates( + this.signallers, + true // + ); + + // + // Now Must to Initialize Provider ... + result = provider.Init( + this.inputs // + ); + + // + return result; + } + + // + // Cleanup ... + void Clean() + { + // + signal.Clean(); + conditions.Clear(); + } + + // + // Validate ... + bool IsValid(bool validateInputs = true) + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) && + NotEmpty(staticVolume) && + (validateInputs + ? inputs.IsValid() + : true) && + (allowLong || allowShort) && + ArraySize(signallers) > 0 + // + ; + + // + return result; + } + + // + // Check Signal ... + bool HasSignal(int barIndex = 0) + { + // + bool result = false; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + // Clear Signal and Conditions ... + Clean(); + + // + result = provider.HasSignal( + barIndex, + signal, + conditions // + ); + + // + return result; + } +}; + +// +void GetAllX121SignalProviders(ENUM_X121_SIGNAL_PROVIDERS &result[]) +{ + // + Clean(result); + + // + Add(XSP, result); + Add(XTEST, result); + Add(X786, result); + Add(X121, result); + Add(X110, result); + Add(X92, result); + Add(X128, result); + Add(XTD, result); + Add(XTAM, result); + Add(XSI, result); + Add(XTSFI, result); + Add(XOBDLH, result); + Add(XCHMACC, result); + Add(XCHMAMN, result); + Add(XCHMAMX, result); +} + +// +string ToString(ENUM_X121_SIGNAL_PROVIDERS value) +{ + return EnumToString(value); +} + +// +ENUM_X121_SIGNAL_PROVIDERS ToX121SignalProvider(string content) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = PROVIDER_NONE; + + // + if (!IsValid(content)) + { + return result; + } + + // + if (content == ToString(PROVIDER_NONE)) + { + result = PROVIDER_NONE; + } + else if (content == ToString(XSP)) + { + result = XSP; + } + else if (content == ToString(XTEST)) + { + result = XTEST; + } + else if (content == ToString(X786)) + { + result = X786; + } + else if (content == ToString(X121)) + { + result = X121; + } + else if (content == ToString(X110)) + { + result = X110; + } + else if (content == ToString(X92)) + { + result = X92; + } + else if (content == ToString(X128)) + { + result = X128; + } + else if (content == ToString(XTD)) + { + result = XTD; + } + else if (content == ToString(XTAM)) + { + result = XTAM; + } + else if (content == ToString(XSI)) + { + result = XSI; + } + else if (content == ToString(XTSFI)) + { + result = XTSFI; + } + else if (content == ToString(XOBDLH)) + { + result = XOBDLH; + } + else if (content == ToString(XCHMACC)) + { + result = XCHMACC; + } + else if (content == ToString(XCHMAMN)) + { + result = XCHMAMN; + } + else if (content == ToString(XCHMAMX)) + { + result = XCHMAMX; + } + + // + return result; +} + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xea.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xea.class.mq5 new file mode 100644 index 0000000..618e05d --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xea.class.mq5 @@ -0,0 +1,1811 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121EA +// Description: provides all X121 EA requirements ... +// - X5 Provider; +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xea.class.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// Define On Signal Event Handler Type Specified for X5 ... +typedef void (*TX121OnSignal)(X121ProviderDescriptor &descriptor); + +// +// Class Definition ... + +class XSCX121EA : public XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCX121EA( + // + // XTrade Class Requirements ... + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + int manageInterval, // Manager Check Intervals Seconds + double maxAllowedSpread, // Max Allowed Spred for Opening Trades + int maxAllowedPositions, // Max Allowed Positions + double maxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + double staticVolume, // Static Volume for Positions + // + // Position Management ... + bool allowLong = true, // Allow Long Trades + bool allowShort = true, // Allow Short Trades + double minProfitPerTrade = 0, // Min Profit Per Trade based On Volume Factor (Hedge) + double minProfitPerVolumeFactor = 0, // Min Volume Factor for Calculating Profit (Hedge) + // + // Event Handlers ... + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL, // On Trade State Changed Event Handler + // + TOnSignal onSignalHandler = NULL, // On Signal Event Handler + // + // Log Handler ... + bool enableAlerts = true, // Enable Alerts + bool logAlerts = true, // Log Alerts + bool terminalAlerts = false, // Terminal Alerts + bool mailAlerts = false, // Mail Alerts + bool pushAlerts = false // Push Alerts + ) : XSCBaseEA(slippage, + magicNumber, + manageInterval, + maxAllowedSpread, + maxAllowedPositions, + maxAllowedDrawdownFactor, + staticVolume, + allowLong, + allowShort, + minProfitPerTrade, + minProfitPerVolumeFactor, + onStopLossTriggered, + onTakeProfitTriggered, + onDealsChangedHandler, + onOrdersChangedHandler, + onPositionsChangedHandler, + onTradeStateChangedHandler, + enableAlerts, + logAlerts, + terminalAlerts, + mailAlerts, + pushAlerts // + ) + { + } + + // + // Deconstructor ... + ~XSCX121EA() {} + + // + // Properties Getter(s) / Setter(s) ... + + // + // Add X5 Specified Signal Event Handler ... + void AddOnSignalEventHandler(TX121OnSignal listener) + { + // + Add( + listener, + mX121OnSignalEventHandlers + // + ); + } + + // + // Add Specified X5 Provider ... + bool AddProvider(X121ProviderDescriptor &descriptor) + { + // + bool result = false; + + // + // Validate Inputs ... + result = descriptor.Init(); + if (!result) + { + return result; + } + + // + AddRef( + descriptor, + mDescriptors // + ); + + // + return result; + } + + // + // Overrides ... + + // + // Customize Token ... + string GetToken() override + { + return GetSpecificToken(this); + } + + // + string GetTag() override + { + return this.GetToken(); + } + + // + void Draw() override + { + // + int descriptorsCount = CountDescriptors(); + if (descriptorsCount <= 0) + { + return; + } + + // + for (int i = 0; i < descriptorsCount; i++) + { + // + X121ProviderDescriptor iDescriptor = mDescriptors[i]; + + // + iDescriptor.provider.Draw(); + } + } + + // + // Check Provider for any Guards ... + bool CheckForGuard(XGuard &guards[]) override + { + // + bool result = false; + + // + Clean(guards); + + // + int descriptorsCount = CountDescriptors(); + result = descriptorsCount > 0; + if (!result) + { + return result; + } + + // + for (int i = 0; i < descriptorsCount; i++) + { + // + X121ProviderDescriptor iDescriptor = mDescriptors[i]; + + // + XGuard iGuards[]; + bool iHasGuard = iDescriptor.provider.HasGuard(iGuards); + if (iHasGuard) + { + // + Copy( + iGuards, + guards, + false // + ); + } + } + + // + result = ArraySize(guards) > 0; + + // + return result; + } + + // + // Request Provider to Collect all + // Potentially Signals and then + // filters theme here and passed them + // for Executing ... + int RequestForSignal( + XSignal &signals[] // Holds Signals ... + ) override + { + // + bool result = 0; + + // + Clean(signals); + + // + int descriptorsCount = CountDescriptors(); + if (descriptorsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < descriptorsCount; i++) + { + // + X121ProviderDescriptor iDescriptor = mDescriptors[i]; + + // + bool iHasSignal = iDescriptor.HasSignal(); + if (iHasSignal) + { + // + // Here we Can double check Signals by Conditions + // for Score Base Filtering ... + + // + AddRef( + iDescriptor.signal, + signals + // + ); + + // + NotifyX121OnSignalEventHandlers(iDescriptor); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Handl Management Actions ... + // if returns true, it is going to prevent for processing forward ... + bool HandleStateManagement(XSignal &signals[]) override + { + // + bool result = false; + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (positionsCount <= 0) + { + return result; + } + + // + // Synch Position Tracker ... + SyncPositionTracker(); + + // + HandleEQMState(signals); + + // + HandleEQMHedge(positions); + + // + HandleTrailManagement(positions); + + // + // Close all Positions on 22 ... + // TODO: Make it Configurable ... + int closeHour = -1; + MqlDateTime cTime = GetCurrentTime(); + if (closeHour >= 0 && cTime.hour == closeHour) + { + // + string comment = "EQM Close on Time ..."; + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (positionsCount <= 0) + { + return result; + } + + // + int closed = mTrader.Close( + positions, + comment // + ); + if (closed > 0) + { + mAlert.Alert(comment); + } + } + + // + // Must false ... + return result; + } + + // + void HandleEQMHedge(XPosition &positions[]) + { + // + // TODO: + // Make them Configurable ... + int numberOfPositionsForHege = 3; + + // + if (!IsHedgeEnable()) + { + return; + } + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + // Hedge ... + if (positionsCount >= numberOfPositionsForHege) + { + // + int maxAllowedPositions = GetMaxAllowedPositions(); + + // + double profit = CalculatePositionsProfit(positions); + double requiredProfit = CalculateRequiredProfitForHedge(positions); + + // + bool isReadyForHedge = + positionsCount < maxAllowedPositions + ? profit >= requiredProfit + : positionsCount >= maxAllowedPositions && profit >= (requiredProfit * 0.80) + ? true + : false; + if (!isReadyForHedge) + { + return; + } + + // + string comment = "EQM Hedge ..."; + int closed = mTrader.Close( + positions, + comment); + if (closed > 0) + { + // + string message = "EQM Hedge Positions on Profit: " + ToString(profit); + + // + mAlert.Alert(message); + + // + RemoveEQMOrders(); + + // + for (int i = 0; i < positionsCount; i++) + { + RemoveTrail(positions[i].ticket); + } + } + } + } + + // + void HandleEQMState(XSignal &signals[]) + { + // + XSignal accepted[]; + bool equityReached = !mTrader.CheckEquityForTrade(); + bool maxAllowedReached = !mTrader.CheckPositionsForTrade(); + bool enableEQM = equityReached || maxAllowedReached; + if (!enableEQM) + { + return; + } + + // + int signalsCount = ArraySize(signals); + if (IsValidSize(signalsCount)) + { + // + // Extract required Data ... + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions); + if (!IsValidSize(positionsCount)) + { + return; + } + + // + int longs = 0; + double longProfits = 0; + double longVolumes = 0; + + // + int shorts = 0; + double shortProfits = 0; + double shortVolumes = 0; + + // + CountPositions( + positions, + longs, + longProfits, + longVolumes, + shorts, + shortProfits, + shortVolumes // + ); + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + bool isLong = IsLong(iSignal.type); + + // + bool canAccept = + // + isLong + ? longs == 0 + : shorts == 0 + // + ; + if (!canAccept) + { + continue; + } + + // + iSignal.provider = XEQMSupportToken; + + // + AddRef( + iSignal, + accepted // + ); + } + + // + int acceptedCount = ArraySize(accepted); + if (!IsValidSize(acceptedCount)) + { + return; + } + + // + // Execute EQM Signals ... + ENUM_X_SIGNAL_EXECUTION_RESULT reasons[]; + int executed = mTrader.ExecuteSignals( + accepted, + reasons, + ORDER_TIME_GTC, + NULL, + false // + ); + if (executed > 0) + { + // + string message = "EQM Execute " + ToString(executed) + " Signals ..."; + + // + mAlert.Alert(message); + } + } + } + + // + // Add Or Update EQM Orders ... + void PlaceEQMOrders(XPosition &position) + { + // + // TODO: Make It Configurable ... + int maxEQMCount = 5; + return; + + // + // Position Protection Senarioos ... + if (!position.IsValid()) + { + return; + } + + // + int descriptorIDX = FindDescriptorIndex(position); + if (descriptorIDX <= -1) + { + return; + } + + // + X121ProviderDescriptor descriptor = mDescriptors[descriptorIDX]; + + // + XOHCLSupRes slSupRes; + bool hasSupRes = descriptor + .provider + .GenerateSupRes( + slSupRes, + position.type, + 5 // + ); + + // + XDrawSpecifications supDrawSpecs; + supDrawSpecs.draw = true; + supDrawSpecs.rayRight = true; + supDrawSpecs.clr = clrLightGreen; + + //, + XDrawSpecifications resDrawSpecs; + resDrawSpecs.draw = true; + resDrawSpecs.rayRight = true; + resDrawSpecs.clr = clrLightCoral; + + // + // DrawSupRes( + // slSupRes, + // supDrawSpecs, + // resDrawSpecs // + // ); + + // + XSignal supports[]; + int supportsCount = GenerateEQMOrders( + supports, + position, + slSupRes // + ); + if (!IsValidSize(supportsCount)) + { + return; + } + + // + XOrder untriggeredOrders[]; + int untriggeredOrdersCount = mTrader.GetOrders( + untriggeredOrders, + position.symbol, + XEQMSupportToken, + position.period, + NULL, // All Types ... + ORDER_STATE_PLACED, + true // + ); + + // + XPosition triggereSupports[]; + int tiggeredSupportsCount = mTrader.GetPositions( + triggereSupports, + position.symbol, + XEQMSupportToken, + position.period, + NULL, // All Types ... + true // + ); + + // + if (untriggeredOrdersCount + + tiggeredSupportsCount >= + maxEQMCount) + { + return; + } + + // + XSignal filteredSignals[]; + for (int i = 0; i < supportsCount; i++) + { + // + XSignal iSupport = supports[i]; + + // + double sl; + iSupport.RegularSL(sl); + + // + double tp; + iSupport.RegularTP(tp); + + // + if (!IsValidSize(untriggeredOrdersCount) && !IsValidSize(tiggeredSupportsCount)) + { + // + AddRef( + iSupport, + filteredSignals // + ); + + // + continue; + } + + // + bool isOrdersPassed = true; + if (!IsValidSize(untriggeredOrdersCount)) + { + isOrdersPassed = true; + } + else + { + // + for (int j = 0; j < untriggeredOrdersCount; j++) + { + // + XOrder jOrder = untriggeredOrders[j]; + + // + bool isSame = + // + jOrder.symbol == iSupport.symbol && + jOrder.period == iSupport.period && + jOrder.openPrice == iSupport.entry && + jOrder.sl == sl && + jOrder.tp == tp + // + ; + if (isSame) + { + // + isOrdersPassed = false; + break; + } + } + } + + // + bool isPositionsPassed = true; + if (!IsValidSize(tiggeredSupportsCount)) + { + isPositionsPassed = true; + } + else + { + // + for (int j = 0; j < tiggeredSupportsCount; j++) + { + // + XPosition jPosition = triggereSupports[j]; + + // + bool isSame = + // + jPosition.symbol == iSupport.symbol && + jPosition.period == iSupport.period && + jPosition.entry == iSupport.entry && + jPosition.sl == sl && + jPosition.tp == tp + // + ; + if (isSame) + { + // + isPositionsPassed = false; + break; + } + } + } + + // + if (isOrdersPassed && + isPositionsPassed) + { + // + AddRef( + iSupport, + filteredSignals // + ); + } + } + int filteredSignalsCount = ArraySize(filteredSignals); + if (!IsValidSize(filteredSignalsCount)) + { + return; + } + + // + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int placedOrders = mTrader.ExecuteSignals( + filteredSignals, + states, + ORDER_TIME_GTC, + NULL, + false // Ignore Policies ... + ); + if (placedOrders > 0) + { + // + string message = "EQM Placed (" + ToString(placedOrders) + ") Support Orders ..."; + + // + mAlert.Alert(message); + } + } + + // + void RemoveEQMOrders() + { + // + XOrder untriggeredOrders[]; + int untriggeredOrdersCount = mTrader.GetOrders( + untriggeredOrders, + NULL, + XEQMSupportToken, + NULL, + NULL, // All Types ... + ORDER_STATE_PLACED, + true // + ); + if (!IsValidSize(untriggeredOrdersCount)) + { + return; + } + + // + int canceleds = mTrader.CancelOrders( + untriggeredOrders // + ); + if (canceleds > 0) + { + // + string message = "EQM Cancel Support ..."; + + // + mAlert.Alert(message); + } + } + + // + void HandleTrailManagement(XPosition &positions[]) + { + // + // TODO: + // Make them Configurable ... + int maxTrailTPs = 5; + // int levelsOnClose = 6; + int riskFreeLevel = 0; + int requiredAgeForTrail = 0; + int requiredDistanceForTrail = 50; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + double profit = CalculatePositionsProfit(positions); + + // + // Trail Positions Stop ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool canManageState = + // + true + // iPosition.provider != XEQMSupportToken + // && + // iPosition.provider != "WSC" + // + ; + + // + // Position Management for X786 ... + if (canManageState) + { + // + // When Position in Profit, Trail SL ... + if (profit > 0) + { + // + if (iPosition.profit > 0) + { + // + XTrail trail; + bool isTrailedBefore = GetSLTrail( + iPosition.ticket, + trail // + ); + + // + if (!isTrailedBefore) + { + // + // Add First Time ... + + // + // Check Position Age ... + int iPositionAge = iPosition.GetAge(iPosition.period); + if (iPositionAge < requiredAgeForTrail) + { + continue; + } + + // + // Check Position Profit Distance ... + // double reward = MathAbs(iPosition.tp - iPosition.entry); + double priceDistanceInPoint = PriceToPoint(iPosition.profit / iPosition.volume, iPosition.symbol); + double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); + if (priceDistance < requiredDistanceForTrail) + { + continue; + } + + // + double slDiff = PointToPrice(priceDistance, iPosition.symbol); + double appliedSL = slDiff / 2; + + // + // double sl = + // IsLong(iPosition.type) + // ? iPosition.sl + appliedSL + // : iPosition.sl - appliedSL; + + // + double sl = + IsLong(iPosition.type) + ? iPosition.entry + appliedSL + : iPosition.entry - appliedSL; + + // + // double sl = + // IsLong(iPosition.type) + // ? iPosition.entry + appliedSL + // : iPosition.entry - appliedSL; + + // + bool isInit = trail.Init( + iPosition.ticket, + iPosition.type, + iPosition.profit, + iPosition.sl, + sl // + ); + if (!isInit) + { + continue; + } + } + else + { + // + // Update Exists ... + + // + // Check Profit ... + bool isProfitPassed = iPosition.profit > trail.profit; + if (!isProfitPassed) + { + continue; + } + + // + // Check Age Distance from Last ... + int age = iBarShift( + iPosition.symbol, + iPosition.period, + trail.time, + false // + ); + if (age < requiredAgeForTrail) + { + continue; + } + + // + double priceDistanceInPoint = PriceToPoint((iPosition.profit - trail.profit) / iPosition.volume, iPosition.symbol); + double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); + if (priceDistance < requiredDistanceForTrail) + { + continue; + } + + // + bool isLong = IsLong(iPosition.type); + + // + double slDiff = PointToPrice(priceDistance, iPosition.symbol); + double appliedSL = (slDiff / 2); + + // + double selectedValue = + // + (riskFreeLevel > 0 && + trail.level == riskFreeLevel) || + (isLong + ? iPosition.sl < iPosition.entry + : iPosition.sl > iPosition.entry) + ? iPosition.entry + : iPosition.sl + // + ; + if (riskFreeLevel > 0 && trail.level > riskFreeLevel) + { + appliedSL = slDiff; + } + + // + double sl = + isLong + ? selectedValue + appliedSL + : selectedValue - appliedSL; + + // + // Update Trail Values ... + bool isUpdated = trail.Update( + sl, + iPosition.profit // + ); + if (!isUpdated) + { + continue; + } + } + + // + if (trail.IsValid()) + { + // + string comment = trail.GenerateTag(); + bool isModified = mTrader.Modify( + trail.ticket, + trail.after, + iPosition.tp, + comment // + ); + if (isModified) + { + // + RemoveTrail(trail.ticket); + + // + AddSLTrail(trail); + + // + string message = "Position (" + ToString(trail.ticket) + ") Trailed SL on Level: " + ToString(trail.level); + mAlert.Alert(message); + } + } + } + } + + // + // When Position in Drawdown Trail TP ... + if (profit < 0) + { + // + if (iPosition.profit < 0) + { + // + XTrail trail; + bool isTrailedBefore = GetTPTrail( + iPosition.ticket, + trail // + ); + + // + if (!isTrailedBefore) + { + // + // Add First Time ... + + // + // Check Position Age ... + int iPositionAge = iPosition.GetAge(iPosition.period); + if (iPositionAge < requiredAgeForTrail) + { + continue; + } + + // + // Check Position Profit Distance ... + double priceDistanceInPoint = PriceToPoint(MathAbs(iPosition.profit) / iPosition.volume, iPosition.symbol); + double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); + if (priceDistance < requiredDistanceForTrail) + { + continue; + } + + // + double tpDiff = PointToPrice(priceDistance, iPosition.symbol); + double appliedTP = tpDiff / 2; + + // + double tp = + IsLong(iPosition.type) + ? iPosition.tp - appliedTP + : iPosition.tp + appliedTP; + + // + bool isInit = trail.Init( + iPosition.ticket, + iPosition.type, + iPosition.profit, + iPosition.tp, + tp // + ); + if (!isInit) + { + continue; + } + } + else + { + // + // Update Exists ... + + // + if (trail.level >= maxTrailTPs) + { + continue; + } + + // + // Check Profit ... + bool isProfitPassed = MathAbs(iPosition.profit) > MathAbs(trail.profit); + if (!isProfitPassed) + { + continue; + } + + // + // Check Age Distance from Last ... + int age = iBarShift( + iPosition.symbol, + iPosition.period, + trail.time, + false // + ); + if (age < requiredAgeForTrail) + { + continue; + } + + // + double priceDistanceInPoint = PriceToPoint((MathAbs(iPosition.profit) - MathAbs(trail.profit)) / iPosition.volume, iPosition.symbol); + double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); + + // + bool isLong = IsLong(iPosition.type); + + // + double tpDiff = PointToPrice(priceDistance, iPosition.symbol); + double appliedTP = tpDiff / 2; + + // + double tp = + isLong + ? iPosition.tp - appliedTP + : iPosition.tp + appliedTP; + + // + // Update Trail Values ... + bool isUpdated = trail.Update( + tp, + iPosition.profit // + ); + if (!isUpdated) + { + continue; + } + } + + // + if (trail.IsValid()) + { + // + string comment = trail.GenerateTag(); + bool isModified = mTrader.Modify( + trail.ticket, + iPosition.sl, + trail.after, + comment // + ); + if (isModified) + { + // + RemoveTrail(trail.ticket); + + // + AddTPTrail(trail); + + // + string message = "Position (" + ToString(trail.ticket) + ") Trailed TP on Level: " + ToString(trail.level); + mAlert.Alert(message); + } + } + } + } + } + } + } + + // + // Here we Can Filter Signals before Sending them to Execution ... + // based on Providers and etc ... + // for Volumes and Benefits ... + int HandleSignalManagement(XSignal &signals[]) override + { + // + // TODO: Make this Configurable ... + int minDistanceBetweenTwoSameProviderSignal = 7; + + // + int result = 0; + + // + if (ArraySize(signals) <= 0) + { + return result; + } + + // + // Create temp Array for Filtering ... + XSignal tmps[]; + Copy( + signals, + tmps // + ); + int tmpsCount = ArraySize(tmps); + + // + // Cleaning Source ... + Clean(signals); + + // + XSignal mEQMManaged[]; + + // + // Loop through Signals for Management ... + for (int i = 0; i < tmpsCount; i++) + { + // + XSignal iSignal = tmps[i]; + + // + // dont Manage NON Signal Provider's signals ... + string provider = iSignal.provider; + bool canIgnore = !IsValid(provider) || provider == "EQM"; + if (canIgnore) + { + // + AddRef( + iSignal, + signals // + ); + + // + continue; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions, + iSignal.symbol, + iSignal.provider, + NULL, // All Periods ... + iSignal.type // + ); + XPosition symbolPositions[]; + int symbolPositionsCount = mTrader.GetPositions( + positions, + iSignal.symbol, + NULL, // All Providers ... + NULL, // All Periods ... + iSignal.type // + ); + double profit = CalculatePositionsProfit(positions); + double symbolProfit = CalculatePositionsProfit(symbolPositions); + if (positionsCount <= 0) + { + // + // First Signal in a While of Specific Provider ... + + // + AddRef( + iSignal, + signals // + ); + + // + continue; + } + // + else if (positionsCount < GetMaxAllowedPositions()) + { + // + // Next Signal in a While of Specific Provider ... + + // + AddRef( + iSignal, + signals // + ); + + // + continue; + } + // + else + { + // + AddRef( + iSignal, + mEQMManaged // + ); + } + + // else if (profit > 0 && symbolProfit > 0) + // { + // // + // AddRef( + // iSignal, + // signals // + // ); + // } + } + + // + if (IsValidSize(ArraySize(mEQMManaged))) + { + HandleEQMState(mEQMManaged); + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Request for Support Signals using Guard ... + bool RequestForSupport( + XSignal &support, // Holds Support Signal, if Provided + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) override + { + // + // TODO: Implement this ... + + // + // Support Senario ... + // Check Support Position Exists or not ... + // Check Positions for Support based on Types ... + // Update Untriggered Positions ... + return false; + } + + // + // Tools ... + + // + // Management Tracker/Profit etc ... + + // + // Handle Position Changed Event ... + void OnPositionsChangedHandler(int count) override + { + // + // Synchronize Tracker ... + SyncPositionTracker(); + } + + // + // Called when a Position Going in Profit ... + void OnPositionGoingInProfit(XPositionTrack &track) override + { + // + string message = "Position (" + ToString(track.ticket) + ", " + track.symbol + ") Dropped in Profit ..."; + + // + mAlert.Alert(message); + } + + // + // Called when a Position Going to Drawdown ... + void OnPositionGoingToDrawdown(XPositionTrack &track) override + { + // + string message = "Position (" + ToString(track.ticket) + ", " + track.symbol + ") Dropped in Drawdown ..."; + + // + mAlert.Alert(message); + } + + // + // Called when Account Going in Profit ... + void OnGoingToProfit(XProfitTrack &track) override + { + // + string message = "Account In Profit ..."; + + // + mAlert.Alert(message); + + // + RemoveEQMOrders(); + } + + // + // Called when Account Going in Drawdown ... + void OnGoingToDrawdown(XProfitTrack &track) override + { + // + string message = "Account In Drawdown ..."; + + // + mAlert.Alert(message); + + // + // Here i Have to Detect In DrawDown Positions ... + + // + RemoveEQMOrders(); + + // + string mSymbols[]; + XSCPositionHolder *mHolders[]; + int symbolsCount = FilterSymbolBasedPositions( + mSymbols, + mHolders // + ); + + // + for (int i = 0; i < symbolsCount; i++) + { + // + string iSymbol = mSymbols[i]; + XSCPositionHolder *iHolder = mHolders[i]; + + // + XPosition iMaxInDP; + bool hasMaxInDP = iHolder.GetMaxInDrawdown(iMaxInDP); + if (!hasMaxInDP) + { + continue; + } + + // + // Try to Protect a Position ... + ProtectPosition(iMaxInDP); + } + } + + // + void ManageUnExecutedSignals( + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], + XSignal &unExecutedSignals[] // + ) override + { + // + XSignal filteredSignals[]; + + // + int unExecutedSignalsCount = ArraySize(unExecutedSignals); + if (!IsValidSize(unExecutedSignalsCount)) + { + return; + } + + // + for (int i = 0; i < unExecutedSignalsCount; i++) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT iState = states[i]; + bool isStateValid = + // + iState == X_SIGNAL_EXECUTION_FAILED_NO_EQUITY || + iState == X_SIGNAL_EXECUTION_FAILED_MAX_REACHED + // + ; + if (!isStateValid) + { + continue; + } + + // + AddRef( + unExecutedSignals[i], + filteredSignals // + ); + } + + // + int filteredSignalsCount = ArraySize(filteredSignals); + if (!IsValidSize(filteredSignalsCount)) + { + return; + } + + // + HandleEQMState(filteredSignals); + } + + // + // Protected ... +protected: + // + // Tools ... + + // + void NotifyX121OnSignalEventHandlers(X121ProviderDescriptor &descriptor) + { + // + int listenersCount = ArraySize(mX121OnSignalEventHandlers); + if (listenersCount <= 0) + { + return; + } + + // + for (int i = 0; i < listenersCount; i++) + { + // + TX121OnSignal iListener = mX121OnSignalEventHandlers[i]; + + // + iListener(descriptor); + } + } + + // + // Protect Specified Position ... + void ProtectPosition(XPosition &position) + { + // + // Here i Can Protect Position ... + // This Protect Include One Position in Market Mode ... + // If Provided ... + // the Positions Selection must passed Some conditions ... + + // + string message = "For (" + position.symbol + ") Max In Drawdown Position is: (" + + ToString(position.ticket) + "), by Profit: " + ToString(position.profit); + + // + mAlert.Alert(message); + } + + // + // Private ... +private: + // + // Props ... + + // + // Collection of Signal Event Listeners ... + TX121OnSignal mX121OnSignalEventHandlers[]; + + // + // a Collection of X5 Provider Descriptors ... + X121ProviderDescriptor mDescriptors[]; + + // + int CountDescriptors() + { + return ArraySize(mDescriptors); + } + + // + // Find Specifc Descriptor ... + int FindDescriptorIndex( + string symbol, + ENUM_TIMEFRAMES period // + ) + { + // + int result = -1; + + // + if (!IsValid(symbol) || + !IsValid(period)) + { + return result; + } + + // + int descriptorsCount = CountDescriptors(); + if (!IsValidSize(descriptorsCount)) + { + return result; + } + + // + for (int i = 0; i < descriptorsCount; i++) + { + // + X121ProviderDescriptor iDescriptor = mDescriptors[i]; + + // + bool isPassed = + // + iDescriptor.symbol == symbol && + iDescriptor.period == period + // + ; + if (isPassed) + { + // + result = i; + break; + } + } + + // + return result; + } + + template + int FindDescriptorIndex( + T &item // + ) + { + return FindDescriptorIndex( + item.symbol, + item.period // + ); + } + + // + // Trails Holding ... + + // + XTrail mSLTrails[]; + XTrail mTPTrails[]; + + // + int CountSLTrails() + { + return ArraySize(mSLTrails); + } + int CountTPTrails() + { + return ArraySize(mTPTrails); + } + + // + bool RemoveTrail(ulong ticket) + { + // + bool isSLRemoved = RemoveSLTrail(ticket); + bool isTPRemoved = RemoveTPTrail(ticket); + + // + bool result = isSLRemoved || isTPRemoved; + + // + return result; + } + bool RemoveSLTrail(ulong ticket) + { + // + bool result = false; + + // + int idx = FindSLTrailIndex(ticket); + result = idx >= 0; + if (!result) + { + return result; + } + + // + result = ArrayRemove( + mSLTrails, + idx, + 1 // + ); + + // + return result; + } + bool RemoveTPTrail(ulong ticket) + { + // + bool result = false; + + // + int idx = FindTPTrailIndex(ticket); + result = idx >= 0; + if (!result) + { + return result; + } + + // + result = ArrayRemove( + mTPTrails, + idx, + 1 // + ); + + // + return result; + } + + // + int FindSLTrailIndex(ulong ticket) + { + // + int result = -1; + + // + int trailsCount = CountSLTrails(); + if (ticket <= 0 || trailsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < trailsCount; i++) + { + // + XTrail iTrail = mSLTrails[i]; + + // + if (iTrail.ticket == ticket) + { + // + result = i; + break; + } + } + + // + return result; + } + int FindTPTrailIndex(ulong ticket) + { + // + int result = -1; + + // + int trailsCount = CountTPTrails(); + if (ticket <= 0 || trailsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < trailsCount; i++) + { + // + XTrail iTrail = mTPTrails[i]; + + // + if (iTrail.ticket == ticket) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + bool GetSLTrail( + ulong ticket, + XTrail &trail // + ) + { + // + bool result = false; + + // + int idx = FindSLTrailIndex(ticket); + result = idx >= 0; + if (!result) + { + return result; + } + + // + trail = mSLTrails[idx]; + + // + return result; + } + bool GetTPTrail( + ulong ticket, + XTrail &trail // + ) + { + // + bool result = false; + + // + int idx = FindTPTrailIndex(ticket); + result = idx >= 0; + if (!result) + { + return result; + } + + // + trail = mTPTrails[idx]; + + // + return result; + } + + // + void AddSLTrail( + XTrail &trail // + ) + { + // + if (!trail.IsValid()) + { + return; + } + + // + AddRef( + trail, + mSLTrails // + ); + } + void AddTPTrail( + XTrail &trail // + ) + { + // + if (!trail.IsValid()) + { + return; + } + + // + AddRef( + trail, + mTPTrails // + ); + } + + // + // Tools ... +}; + +// +// Tools ... + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xmcycle.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xmcycle.class.mq5 new file mode 100644 index 0000000..aaa7751 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.x121.xmcycle.class.mq5 @@ -0,0 +1,7380 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSC121MCycle +// Description: provides all requirements for +// Handling Specified Market Cycle Analysis... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +#include "../Helpers/x-saherelm.xtd.helper.mq5" +#include "../Helpers/x-saherelm.xhk.helper.mq5" +#include "../Helpers/x-saherelm.xmc.helper.mq5" +#include "../Helpers/x-saherelm.xpv.helper.mq5" +#include "../Helpers/x-saherelm.xzg.helper.mq5" +#include "../Helpers/x-saherelm.xmrb.helper.mq5" +#include "../Helpers/x-saherelm.xdon.helper.mq5" +#include "../Helpers/x-saherelm.xche.helper.mq5" +#include "../Helpers/x-saherelm.xosc.helper.mq5" +#include "../Helpers/x-saherelm.xstr.helper.mq5" +#include "../Helpers/x-saherelm.xich.helper.mq5" + +// +#include "../Classes/x-saherelm.xprovider.class.mq5" + +// +// Definitions ... + +// +// X121 Specified Market Cycle Structure ... +class X121MCycleInputs : public XSCBaseProviderInpts +{ + // + // Public ... +public: + // + // Props ... + + // + XMarketCycle cycle; // Cycle Descriptor ... + + // + // Draw Props ... + + // + XDrawSpecifications cBarMidDrawSpecs; // Current Bar MidLine Draw Specifications + XOHCLDrawSpecification cBarDrawSpecs; // Current Bar Draw Specifications + + // + XDrawSpecifications pBarMidDrawSpecs; // Previous Bar MidLine Draw Specifications + XOHCLDrawSpecification pBarDrawSpecs; // Previous Bar Draw Specifications + + // + bool drawLabels; // Draw Labels + bool drawCBar; // Draw Current Bar + bool drawPBar; // Draw Previous Bar + bool drawCBarMid; // Draw Current Bar Mid Line + bool drawPBarMid; // Draw Previous Bar Mid Line + + // + XHKInputs hkInputs; // HK Inputs ... + XMCInputs mcInputs; // MC Inputs ... + XPVInputs pvInputs; // PV Inputs ... + XZGInputs zgInputs; // ZG Inputs ... + XTDInputs tdInputs; // TD Inputs ... + XMRBInputs mrbInputs; // MRB Inputs ... + XSTRInputs strInputs; // STR Inputs ... + XOSCInputs oscInputs; // OSC Inputs ... + XCHEInputs cheInputs; // CHE Inputs ... + XICHInputs ichInputs; // ICH Inputs ... + XDONInputs donInputs; // DON Inputs ... + + // + // Constructor ... + + // + // Tools ... + + // + // Initialize Market Cycle ... + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + ENUM_TIMEFRAMES mPeriod, // Cycle Period + ENUM_X_PERIOD_METHOD mPeriodMethod, // Cycle Period Method + string mPrefix = "", // Prefix + bool useDefaults = true // Use Inputs Default Settings ... + ) + { + // + bool result = false; + + // + cycle.period = mPeriod; + cycle.method = mPeriodMethod; + + // + // Initial Cycle Model ... + result = cycle.Init( + mSymbol, + mHostPeriod, + mCycle, + mPrefix + // + ); + if (!result) + { + return result; + } + + // + if (useDefaults) + { + // + hkInputs.Default(); + mcInputs.Default(); + pvInputs.Default(); + zgInputs.Default(); + mrbInputs.Default(); + strInputs.Default(); + oscInputs.Default(); + cheInputs.Default(); + ichInputs.Default(); + donInputs.Default(); + } + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Initialize Market Cycle ... + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + XHKInputs &mHkInputs, // HK Inputs + XMCInputs &mMcInputs, // MC Inputs + XPVInputs &mPvInputs, // PV Inputs ... + XZGInputs &mZgInputs, // ZG Inputs ... + XTDInputs &mTdInputs, // TD Inputs ... + XMRBInputs &mMrbInputs, // MRB Inputs ... + XSTRInputs &mStrInputs, // STR Inputs + XOSCInputs &mOscInputs, // OSC Inputs + XCHEInputs &mCheInputs, // CHE Inputs + XICHInputs &mIchInputs, // ICH Inputs ... + XDONInputs &mDonInputs, // DON Inputs ... + int mHostBarIndex = 0, // Specified Host Period Bar Index + string mPrefix = "" // Prefix + ) + { + // + bool result = false; + + // + // Initial Cycle Model ... + result = cycle.Init( + mSymbol, + mHostPeriod, + mCycle, + mPrefix + // + ); + if (!result) + { + return result; + } + + // + hkInputs = mHkInputs; + mcInputs = mMcInputs; + pvInputs = mPvInputs; + zgInputs = mZgInputs; + tdInputs = mTdInputs; + mrbInputs = mMrbInputs; + strInputs = mStrInputs; + oscInputs = mOscInputs; + cheInputs = mCheInputs; + ichInputs = mIchInputs; + donInputs = mDonInputs; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Cleanup ... + virtual void Clean() + { + // + cycle.Clean(); + + // + hkInputs.Clean(); + mcInputs.Clean(); + pvInputs.Clean(); + zgInputs.Clean(); + tdInputs.Clean(); + mrbInputs.Clean(); + strInputs.Clean(); + oscInputs.Clean(); + cheInputs.Clean(); + ichInputs.Clean(); + donInputs.Clean(); + + // + cBarDrawSpecs.Clean(); + pBarDrawSpecs.Clean(); + cBarMidDrawSpecs.Clean(); + pBarMidDrawSpecs.Clean(); + + // + drawLabels = false; + drawCBar = false; + drawPBar = false; + drawCBarMid = false; + drawPBarMid = false; + } + + // + // Default ... + virtual void Default() + { + // + hkInputs.Default(); + mcInputs.Default(); + pvInputs.Default(); + zgInputs.Default(); + tdInputs.Default(); + mrbInputs.Default(); + strInputs.Default(); + oscInputs.Default(); + cheInputs.Default(); + ichInputs.Default(); + donInputs.Default(); + + // + drawLabels = false; + drawCBar = false; + drawPBar = false; + drawCBarMid = false; + drawPBarMid = false; + } + + // + // Validation ... + virtual bool IsValid() + { + // + bool result = false; + + // + result = cycle.IsValid(); + if (!result) + { + return result; + } + + // + result = hkInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = mcInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = pvInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = zgInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = tdInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = mrbInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = strInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = oscInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = cheInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = ichInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = donInputs.IsValid(); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Max ... + virtual int Max() + { + // + int result = 0; + + // + result = MathMax(mcInputs.Max(), strInputs.Max()); + + // + result = MathMax(result, hkInputs.Max()); + result = MathMax(result, mcInputs.Max()); + result = MathMax(result, pvInputs.Max()); + result = MathMax(result, zgInputs.Max()); + result = MathMax(result, tdInputs.Max()); + result = MathMax(result, mrbInputs.Max()); + result = MathMax(result, strInputs.Max()); + result = MathMax(result, oscInputs.Max()); + result = MathMax(result, cheInputs.Max()); + result = MathMax(result, ichInputs.Max()); + result = MathMax(result, donInputs.Max()); + + // + return result; + } +}; + +// +// Specific Market Sense Based on Specified Bar Index on Host Period ... +class X121MCycleConditions : public XSCBaseProviderMarketConditions +{ + // + // Public ... +public: + // + // Props ... + + // + // Common ... + string prefix; // Cycle Prefix ... + ENUM_TIMEFRAMES hostPeriod; // Hosting Time Frame ... + ENUM_X_MARKET_CYCLES cycle; // Init Cycle ... + + // + // Candlestic Conditions ... + bool isLastBullish; + bool isLastBearish; + bool isCurrentBullish; + bool isCurrentBearish; + bool isCurrentMidLineOverLastHigh; + bool isCurrentMidLineUnderLastLow; + bool isCurrentMidLineOverLastUp; + bool isCurrentMidLineUnderLastDown; + bool isCurrentMidLineOverLastMidLine; + bool isCurrentMidLineUnderLastMidLine; + + // + // Buffers ... + + // + XOHCL hkBars[]; + XOHCL smHKBars[]; + + // + // XICH ... + double ichTenkanSens[]; + double ichKijunSens[]; + double ichChikouSpans[]; + double ichSenkouSpanAs[]; + double ichSenkouSpanBs[]; + + // + // XMC ... + double mcFasts[]; + double mcSlows[]; + double mcVerifiers[]; + + // + // XSTR ... + double strTrends[]; + double strStates[]; + + // + // XZG ... + double zigzags[]; + double zigzagPVs[]; + + // + // XMRB ... + + // + double mrbFasts[]; + double mrb1Fasts[]; + double mrb2Fasts[]; + double mrb3Fasts[]; + double mrb4Fasts[]; + double mrb5Fasts[]; + double mrb6Fasts[]; + + // + double mrbSlows[]; + double mrb1Slows[]; + double mrb2Slows[]; + double mrb3Slows[]; + double mrb4Slows[]; + double mrb5Slows[]; + double mrb6Slows[]; + + // + // XCHE ... + double cheLongExit1s[]; + double cheLongExit2s[]; + double cheShortExit1s[]; + double cheShortExit2s[]; + + // + // XDON ... + double donUpperOs[]; + double donLowerOs[]; + double donUpperCs[]; + double donLowerCs[]; + double donUpperHs[]; + double donLowerHs[]; + double donUpperLs[]; + double donLowerLs[]; + + // + // XPV ... + double pvPeaks[]; + double pvVales[]; + double pvResistances[]; + double pvSupports[]; + double pvFib1s[]; + double pvFib2s[]; + double pvFib3s[]; + double pvFib4s[]; + double pvFib5s[]; + double pvSCHHs[]; + double pvSCLLs[]; + double pvMCHHs[]; + double pvMCLLs[]; + double pvLCHHs[]; + double pvLCLLs[]; + double pvHCHHs[]; + double pvHCLLs[]; + + // + // XOSC ... + double oscAtrs[]; + double oscRviMains[]; + double oscRviSignals[]; + double oscBullPs[]; + double oscBearPs[]; + double oscVolumes[]; + double oscRsis[]; + double oscCcis[]; + double oscMomentums[]; + double oscSars[]; + double oscMacdMains[]; + double oscMacdSignals[]; + double oscStochMains[]; + double oscStochSignals[]; + double oscStddevs[]; + + // + // XTD ... + double tdBullishs[]; + double tdBearishs[]; + double tdSignals[]; + + // + // XTD ... + bool isXTDSignalPeak; + bool isXTDSignalVale; + bool isXTDBullishPeak; + bool isXTDBullishVale; + bool isXTDBearishPeak; + bool isXTDBearishVale; + bool isXTDBullOverBear; + bool isXTDBullUnderBear; + bool isXTDSignalOverBear; + bool isXTDSignalUnderBear; + bool isXTDBullCrossedOverBear; + bool isXTDBullCrossedUnderBear; + bool isXTDSignalCrossedOverBear; + bool isXTDSignalCrossedUnderBear; + + // + // XHK ... + + // + bool isHKBullish; + bool isSMHKBullish; + bool isHKBearish; + bool isSMHKBearish; + bool isClosedOverSMHK; + bool isClosedUnderSMHK; + bool isHKBullishPrev; + bool isSMHKBullishPrev; + bool isHKBearishPrev; + bool isSMHKBearishPrev; + bool isClosedOverSMHKPrev; + bool isClosedUnderSMHKPrev; + + // + // XZG ... + + // + bool isZigZagInPeak; + bool isZigZagInVale; + + // + // XDON ... + + // + bool isDONAttachedMaxLower; + bool isDONAttachedMinLower; + bool isDONCrossedOverMaxLower; + bool isDONCrossedUnderMaxLower; + + // + bool isDONAttachedMaxUpper; + bool isDONAttachedMinUpper; + bool isDONCrossedOverMaxUpper; + bool isDONCrossedUnderMaxUpper; + + // + // XPV ... + + // + bool isPVPeakSameAs; + bool isPVNewPeak; + bool isPVNewPeakOverLast; + bool isPVNewPeakUnderLast; + bool isPVValeSameAs; + bool isPVNewVale; + bool isPVNewValeOverLast; + bool isPVNewValeUnderLast; + bool isPVFiboIncreased; + bool isPVFiboDecreased; + bool isPVFiboSectionChanged; + + // + bool isPVSCBullish; + bool isPVSCHHBullish; + bool isPVSCLLBullish; + bool isPVSCSwitchedToBullish; + + // + bool isPVSCBearish; + bool isPVSCHHBearish; + bool isPVSCLLBearish; + bool isPVSCSwitchedToBearish; + + // + bool isPVMCBullish; + bool isPVMCHHBullish; + bool isPVMCLLBullish; + bool isPVMCSwitchedToBullish; + + // + bool isPVMCBearish; + bool isPVMCHHBearish; + bool isPVMCLLBearish; + bool isPVMCSwitchedToBearish; + + // + bool isPVLCBullish; + bool isPVLCHHBullish; + bool isPVLCLLBullish; + bool isPVLCSwitchedToBullish; + + // + bool isPVLCBearish; + bool isPVLCHHBearish; + bool isPVLCLLBearish; + bool isPVLCSwitchedToBearish; + + // + bool isPVHCBullish; + bool isPVHCHHBullish; + bool isPVHCLLBullish; + bool isPVHCSwitchedToBullish; + + // + bool isPVHCBearish; + bool isPVHCHHBearish; + bool isPVHCLLBearish; + bool isPVHCSwitchedToBearish; + + // + // XICH ... + // Ichimoku strategy + // Strategy one: Ichimoku trend identifier: + // According to this strategy, we need a trigger that can be used + // to inform us about the trend type, + // if it is an uptrend or downtrend. + // We will check three values to do that and these values are the: + // closing price, Senkou Span A, and Senkou Span B. + // If the closing price is greater than the Senkou Span B and at the same time + // the closing price is greater than Senkou Span A, + // this will be the trigger to know that the trend is up. + // Vice versa, if the closing price is lower than the Senkou Span B and at the same time + // the closing price is lower than the Senkou Span A, + // this will be the trigger to the downtrend. + // + // Closing price > Senkou Span B and closing price > Senkou Span A --> Uptrend + // Closing price < Senkou Span B and closing price < Senkou Span A --> Downtrend + // + // Strategy two: Ichimoku trend strength: + // Based on this strategy, we need a trigger that can inform us the current trend is strong. + // We will check three values to do that and these values are the: + // - current Senkou Span A, + // - the previous Senkou Span A, and + // - the Senkou Span B. + // If the current Senkou Span A is greater than the previous Senkous Span A and at the same time + // the current Senkou Span A is greater than the Senkou Span B, + // this is a trigger that the trend is up and strong. + // Vice versa, if the current Senkou Span A is lower than the previous Senkou Span A and at the + // same time, the current Senkou Span A is lower than the Senkou Span B, + // this will be a signal that the trend is down and strong. + // + // Current Senkou Span A > previous Senkou Span A and current Senkou Span A > Senkou Span B --> the uptrend is strong + // Current Senkou Span A < previous Senkou Span A and current Senkou Span A < Senkou Span B --> the downtrend is strong + bool isSenkouSpanAOverB; + bool isSenkouSpanAUnderB; + bool isSenkouSpanAOverLast; + bool isSenkouSpanAUnderLast; + bool isFutureSenkouSpanAOverB; + bool isFutureSenkouSpanAUnderB; + bool isFutureSenkouSpanAOverLast; + bool isFutureSenkouSpanAUnderLast; + // + // Strategy three: Ichimoku price-Ki signal: + // According to this strategy, during the uptrend, we need a trigger that can + // alert us about the bullish signal, and during the downtrend, we need a trigger than can alert us about the bearish signal. + // We will check based on this strategy two values, closing price, and Kijun-Sen. + // If the closing price is greater than the Kijun-sen value, + // this will be a trigger to a bullish signal. + // Vice versa, if the closing price is lower than the Kijun-sen value, + // this will be a bearish signal. + // + // During uptrend, closing price > Kijun -sen --> bullish signal + // Duuring downtrend, closing price < Kijun -sen --> bearish signal + bool isCloseOverKijunSen; + bool isCloseUnderKijunSen; + // + // Strategy four: Ichimoku ten-ki signal: + // According to this strategy, during the uptrend, we need another trigger or + // method to alert us when there is a bullish signal or + // during the downtrend, we need a signal of bearishness. + // We will check based on this strategy two values, Tenkan-sen and Kijum-sen. + // If the Tenkan-sen value is greater than the Kijun-sen, + // this will be a signal of bullishness. + // Vice versa, if the Tenkan-sen is lower than the Kijun-sen, + // this will be a signal of bearishness. + // + // Tenkan-sen > Kijun-sen --> bullish signal + // Tenkan-sen < Kijun-sen --> bearish signal + bool isTenkanSenOverKijunSen; + bool isTenkanSenUnderKijunSen; + bool isTenkanSenCrossedOverKijunSen; + bool isTenkanSenCrossedUnderKijunSen; + + // + // XMC ... + // Three Moving Averages Crossover + // In this strategy, we will use three simple moving averages: + // the shorter simple moving average period is 10, the longer one period is 48, and in between a period of 24. + // + // According to the strategy, we need the three simple moving averages to be checked at every tick: + // + // If 10 SMA > 24 SMA, 10 SMA > 48 SMA, and 24 SMA > 48 SMA: the signal will be to buy and we need to be appeared as a comment on the chart. + // If 10 SMA < 24 SMA, 10 SMA < 48 SMA, and 24 SMA < 48 SMA: the signal will be to sell and we need to be appeared as a comment on the chart. + // If anything, else do nothing. + bool isFastOverSlow; + bool isFastUnderSlow; + bool isFastOverVerifier; + bool isFastUnderVerifier; + bool isSlowOverVerifier; + bool isSlowUnderVerifier; + bool isCloseOverFast; + bool isCloseUnderFast; + bool isCloseOverSlow; + bool isCloseUnderSlow; + bool isCloseOverVerifier; + bool isCloseUnderVerifier; + bool isFastCrossedOverSlow; + bool isFastCrossedUnderSlow; + bool isFastCrossedOverVerifier; + bool isFastCrossedUnderVerifier; + bool isSlowCrossedOverVerifier; + bool isSlowCrossedUnderVerifier; + + // + // XSTR ... + bool isTrendBullish; + bool isTrendSwitchedToBullish; + bool isTrendBearish; + bool isTrendSwitchedToBearish; + + // + // XCHE ... + bool isCHEInLong; + bool isCHEInStrongLong; + bool isCHESwitchedInStrongLong; + bool isCHEInShort; + bool isCHEInStrongShort; + bool isCHESwitchedInStrongShort; + + // + // XOSC ... + + // + // RVI Signals ... + // Strategy one: RVI Crossover - Uptrend: + // Based on this strategy, we need to get buy and close signals during the uptrend by a specific condition. + // When the RVI current value and RVI signal current value are greater than the zero level at the same time + // that RVI current value is greater than the current value of the RVI signal, this will be a buy signal. + // Vice Versa, when the RVI current value and RVI signal current value is below zero level at + // the same time that the RVI current value is below the current value of the RVI signal, this will be a close signal. + // + // RVI value > 0 and RVI signal value > 0 and RVI value > RVI signal value --> buy + // RVI value < 0 and RVI signal value < 0 and RVI value < RVI signal value --> close + bool isRVILongStart; + bool isRVILongStop; + // + // Strategy two: RVI Crossover - Downtrend: + // Based on this strategy, we need to get the opposite signals of the previous RVI Crossover - + // Uptrend strategy as we need to get short and cover signals. + // When the RVI current value and RVI signal current value are lower than the zero level at + // the same time that RVI current value is lower than the current value of the RVI signal, this will be a short signal. + // Vice Versa, when the RVI current value and RVI signal current value is above the zero level + // at the same time that the RVI current value is above the current value of the RVI signal, this will be a cover signal. + // + // RVI value < 0 and RVI signal value < 0 and RVI value < RVI signal value --> short + // RVI value > 0 and RVI signal value > 0 and RVI value > RVI signal value --> cover + bool isRVIShortStart; + bool isRVIShortStop; + // + // Strategy three: RVI and MA Crossover + // Based on this strategy, we need to get buy and sell signals based on specific conditions + // as we need to get a + // buy signal + // when the closing price is greater than the 100 -period moving average + // at the same time that the current RVI value is greater than the current RVI signal value. + // In the other scenario, we need to get a + // sell signal + // when the closing price is lower than the 100 -period moving average + // at the same time that the current RVI value is lower than the current RVI signal value. + + // + // RSI strategy ... + // During Uptrend + // In this case, most of the time RSI values move between or moving between + // the mid range and level 70 (Overbought level). + // The trading strategy for the uptrend is: + // + // RSI Value < 50 = Buy + // RSI Value > 70 = Take Profit + bool isRSIUnder50; + bool isRSIOver70; + // + // During Downtrend + // During the downtrend, the RSI moves most of the time between + // the mid range and level 30 (Oversold level). + // The trading strategy will be as follows: + // + // RSI Value > 50 = Short + // RSI Value < 30 = Take Profit + bool isRSIOver50; + bool isRSIUnder30; + // + // During Sideways: + // RSI spends most of the time between levels 30 (Oversold level) and 70 (Oversbought level). + // The trading strategy will be as follows: + // RSI Value < 30 = Buy + // RSI Value > 50 = Take Profit + // RSI Value > 70 = Short + // RSI Value < 50 = Take Profit + + // + // Bull's Power strategy: + // In this part, we will learn how we can use Bull's Power through simple strategies + // that can be used based on the basic concept of this indicator. + // The following are for these strategies and their conditions. + // I need to confirm here, that these strategies for education only as the main objective + // is to understand the main concept behind the indicator and how we can use them in our favor, + // so you must test any of them before using them on your real account to make sure that + // it will be good for your trading as there is no strategy is suitable for everyone. + // + // Strategy one: Bull's Power Movement: + // Based on this strategy, we need to get signals based on the position of current and previous bull's power values. + // If the current bull's power value is greater than the previous one, + // we will consider it as a signal of the rising of the Bull's Power indicator. + // Vice versa, if the current value is lower than the previous one, we will consider that as a signal of + // declining Bull's Power. + // + // To simplify that, it will be the same as the following: + // + // Current Bull's Power > Previous Bull's Power --> Bull's Power is Rising + // Current Bull's Power < Previous Bull's Power --> Bull's Power is declining + bool isBullPowerOverLast; + bool isBullPoswerUnderLast; + // + // Strategy two: Bull's Power - Strong or Divergence + // Based on this strategy, we want to get a signal that informs us if there is a strong movement + // or there is a divergence by evaluating four values and these values are current high, + // the previous high, bull power, and previous bull power. + // If the current high is higher than the previous high and + // the current bull power value is higher than the previous one, + // we will consider that as a signal of a strong move. + // In the other case, if the current high is higher than the previous high and the current + // bull value is lower than the previous one, we will consider that as a signal of bearish divergence. + // + // To simplify that, it will be the same as the following: + // + // Current high > previous high and current bull's power > previous bull's power --> strong move + // Current high < previous high and current bull's power > previous bull's power --> bearish divergence + // + // Strategy three: Bull's Power signals + // Based on this strategy, we need a signal that can be used to get buy and sell signals and we will + // evaluate four values to do that based on this strategy. + // These four values are: + // - current bull's power, + // - zero level, + // - current close value, and + // - current exponential moving average. + // If the current bull's power is lower than the zero level and + // the current close is lower than the exponential moving average, + // we will consider it as a signal of selling. + // If the current bull's power is greater than the zero level and the current close is greater than + // the exponential moving average, this will be a signal of buying. + // + // To simplify that, it will be the same as the following: + // + // Current bull's power < zero level and current close < EMA --> sell + // Current bear's power > zero level and current close > EMA --> buy + bool isBullPowerOverZero; + bool isBullPoswerUnderZero; + + // + // Bear's Power strategy + // In this part, we will learn how we can use Bear's Power through simple strategies + // that can be used based on the basic concept of this indicator. + // The following are for these strategies and their conditions. + // I need to confirm here, that these strategies for education as the main objective + // is to understand the main concept behind the indicator and how we can use it, + // so you must test any of them before using them on your real account to + // make sure that it will be good for your trading. + // + // Strategy one: Bear's Power Movement + // According to this strategy, we need to get signals based on the position of current and previous + // bear's power values. + // If the current value is greater than the previous, this will be a signal of the rising of + // Bear's Power indicator. + // Vice versa, if the current value is lower than the previous value, + // this will be a signal of declining Bear's Power. + // + // Simply, + // + // Current Bear's Power > Previous Bear's Power --> Bear's Power is Rising + // Current Bear's Power < Previous Bear's Power --> Bear's Power is declining + bool isBearPowerOverLast; + bool isBearPoswerUnderLast; + // + // Strategy two: Bear's Power - Strong or Divergence + // According to this strategy, we need to get a signal that informs us if there are strong movements or + // there are divergences by evaluating four values and they are: + // -current low, + // - previous low, + // - bear power, and + // - previous bear power. + // If the current low is lower than the previous low and the current bear power value + // is lower than the previous one, this will be a signal of a strong move. + // In the other case, if the current low is lower than the previous low and the current + // bear value is greater than the previous one, this will be a signal of bullish divergence. + // + // Simply, + // + // Current low < previous low and current bear's power < previous bear's power --> strong move + // Current low < previous low and current bear's power > previous bear's power --> bullish divergence + // + // Strategy three + // According to this strategy, we need a trigger that can be used to get buy and sell signals and + // we will evaluate four values to do that based on this strategy. + // These four values are current: + // - bear's power, + // - zero level, + // - current close value, and + // - current exponential moving average. + // If the current bear's power is greater than the zero level and the current close is greater than + // the exponential moving average, this will be a signal of buy. + // If the current bear's power is lower than the zero level and the current close is lower than + // the exponential moving average, this will be a signal of selling. + // + // Simply, + // + // Current bear's power > zero level and current close > EMA --> buy + // Current bear's power < zero level and current close < EMA --> sell + bool isBearPowerOverZero; + bool isBearPoswerUnderZero; + + // + // CCI ... + bool isCCIPositive; + bool isCCINegative; + bool isCCIOverPositiveHundred; + bool isCCIUnderNegativeHundred; + + // + // STDDEV ... + // Based on this strategy, we need to measure the volatility based on the comparison between the + // current Std Dev and the average of the five previous Std values. + // If the current Std Dev is greater than the Std Dev 5-periods average, this will be a high volatility signal. + // If the current Std is lower than the Std Dev 5- period average, this will be low volatility. + // + // Based on this strategy, we need to get buy and sell signals based on specific conditions. + // If the current Std Dev is greater than the previous Std Dev and the Ask value is greater than the moving average, + // this will be a buy signal. + // If the current Std Dev is greater than the previous Std Dev and the Bid value is lower than the moving average, + // this will be a sell signal. + // + // Current Std > Prev. Std and Ask > MA --> Buy signal + // Current Std > Prev. Std and Bid < MA --> Sell signal + // + // Based on this strategy, we need to get buy and sell signals based on other conditions. + // If the current Std Dev is greater than Std Dev Avg and Ask is greater than the moving average, + // this will be a buy signal. + // If the current Std Dev is greater than Std Dev Avg and Bid is lower than the moving average, + // this will be a sell signal. + // + // Current Std > Std Avg and Ask > MA --> Buy signal + // Current Std > Std Avg and Bid < Ma --> Sell signal + bool isSTDDEVOverAVG; + bool isSTDDEVOverLast; + bool isSTDDEVUnderAVG; + bool isSTDDEVUnderLast; + + // + // MACD ... + // According to this strategy, we need to identify the market setup: + // is it buying setup or shorting setup. + // In other words we need to identify the market direction, if it is bullish or bearish market, + // and this will be identified by MACD. + // If the MACD main line breaks above zero level, this will be a buying setup or bullish setup and + // vice versa if MACD main line breaks below zero level, this will be a shorting setup or bearish. + // + // MACD main line > 0 = Bullish Setup + // MACD main line < 0 = Bearish Setup + // + // According to this strategy, we need to identify generated signals + // if there is a buy signal or a sell signal based on MACD main line and Signal line crossover. + // If MACD main line breaks above Signal line, this will be a buy signal and if MACD main line breaks + // below Signal line, this will be a short signal. + // + // MACD main line > MACD signal line = Buying Signal + // MACD main line < MACD signal line = Shorting signal + bool isMACDPositiove; + bool isMACDNegative; + bool isMACDOverSignal; + bool isMACDUnderSignal; + + // + // STOCHASTIC ... + // Stochastic strategy + // In this part, we will talk about how we can use this indicator through simple strategies. + // We can get signals from the stochastic indicator according to market trend and these strategies are + // uptrend strategy, downtrend strategy, and sideways strategy. + // + // Strategy one: Uptrend strategy + // According to this strategy, we need to check if the %K line and %D line are below the 50 level, + // then, the buy signal will be generated + // when the %K line crosses above the %D line. + // We can take profit according to another effective tool like price action by searching + // for a lower low for example. + // + // %K, %D < 50 --> %K > %D = buy signal + bool isStochKOverD; + bool isStochKDUnder50; + // + // Strategy two: downtrend strategy + // According to this strategy, we need to check if the %K line and %D line are above the 50 level, + // then, the sell signal will be generated + // when the %K line crosses below the %D line. + // We can take profit according to another effective tool like price action by searching + // for a higher high for example. + // + // %K, %D > 50 --> %K < %D = sell signal + bool isStochKUnderD; + bool isStochKDOver50; + // + // Strategy three: sideways strategy + // + // The buy signal: + // According to this strategy, we need to check if the %K line and %D line are below the 20 level, + // then, the buy signal will be generated + // when the %K line crosses above the %D line. + // When the %K line and %D line are above 80, then the take profit signal will be generated + // when the %K line crosses below the %D line. + // %K, %D < 20 --> %K > %D = buy signal + // %K, %D > 80 --> %K < %D = take profit + bool isStochKDUnder20; + // + // The sell signal + // According to this strategy, we need to check if the %K line and %D line are above the 80 level, + // then, the sell signal will be generated + // when the %K line crosses below the %D line. + // When the %K line and %D are below the 20 level, then, the take profit signal will be generated + // when the %K line crosses above the %D line. + // + // %K, %D > 80 --> %K < %D = sell signal + // %K, %D < 20 --> %K > %D = take profit + bool isStochKDOver80; + + // + // XMR ... + bool isMRBFastOverSlow; + bool isMRBFastCrossedOverSlow; + bool isMRBCloseOverFast; + bool isMRBFastUnderSlow; + bool isMRBFastCrossedUnderSlow; + bool isMRBCloseUnderSlow; + + // + // Tools ... + + // + void Clear() + { + // + // Commons ... + time = 0; + cycle = NULL; + prefix = NULL; + symbol = NULL; + period = NULL; + hostPeriod = NULL; + + // + Clean(bars); + + // + // Candlestic ... + isLastBullish = false; + isLastBearish = false; + isCurrentBullish = false; + isCurrentBearish = false; + isCurrentMidLineOverLastHigh = false; + isCurrentMidLineUnderLastLow = false; + isCurrentMidLineOverLastUp = false; + isCurrentMidLineUnderLastDown = false; + isCurrentMidLineOverLastMidLine = false; + isCurrentMidLineUnderLastMidLine = false; + + // + // Buffers ... + Clean(bars); + Clean(hkBars); + Clean(smHKBars); + Clean(ichTenkanSens); + Clean(ichKijunSens); + Clean(ichChikouSpans); + Clean(ichSenkouSpanAs); + Clean(ichSenkouSpanBs); + Clean(mcFasts); + Clean(mcSlows); + Clean(mcVerifiers); + Clean(strTrends); + Clean(strStates); + Clean(cheLongExit1s); + Clean(cheLongExit2s); + Clean(cheShortExit1s); + Clean(cheShortExit2s); + Clean(oscAtrs); + Clean(oscRviMains); + Clean(oscRviSignals); + Clean(oscBullPs); + Clean(oscBearPs); + Clean(oscVolumes); + Clean(oscRsis); + Clean(oscCcis); + Clean(oscMomentums); + Clean(oscSars); + Clean(oscMacdMains); + Clean(oscMacdSignals); + Clean(oscStochMains); + Clean(oscStochSignals); + Clean(oscStddevs); + Clean(zigzags); + Clean(zigzagPVs); + Clean(mrbFasts); + Clean(mrb1Fasts); + Clean(mrb2Fasts); + Clean(mrb3Fasts); + Clean(mrb4Fasts); + Clean(mrb5Fasts); + Clean(mrb6Fasts); + Clean(mrbSlows); + Clean(mrb1Slows); + Clean(mrb2Slows); + Clean(mrb3Slows); + Clean(mrb4Slows); + Clean(mrb5Slows); + Clean(mrb6Slows); + Clean(donUpperOs); + Clean(donLowerOs); + Clean(donUpperCs); + Clean(donLowerCs); + Clean(donUpperHs); + Clean(donLowerHs); + Clean(donUpperLs); + Clean(donLowerLs); + Clean(pvPeaks); + Clean(pvVales); + Clean(pvResistances); + Clean(pvSupports); + Clean(pvFib1s); + Clean(pvFib2s); + Clean(pvFib3s); + Clean(pvFib4s); + Clean(pvFib5s); + Clean(pvSCHHs); + Clean(pvSCLLs); + Clean(pvMCHHs); + Clean(pvMCLLs); + Clean(pvLCHHs); + Clean(pvLCLLs); + Clean(pvHCHHs); + Clean(pvHCLLs); + Clean(tdBullishs); + Clean(tdBearishs); + Clean(tdSignals); + + // + // XTD ... + isXTDSignalPeak = false; + isXTDSignalVale = false; + isXTDBullishPeak = false; + isXTDBullishVale = false; + isXTDBearishPeak = false; + isXTDBearishVale = false; + isXTDBullOverBear = false; + isXTDBullUnderBear = false; + isXTDSignalOverBear = false; + isXTDSignalUnderBear = false; + isXTDBullCrossedOverBear = false; + isXTDBullCrossedUnderBear = false; + isXTDSignalCrossedOverBear = false; + isXTDSignalCrossedUnderBear = false; + + // + // Buffers ... + ArraySetAsSeries(bars, true); + ArraySetAsSeries(hkBars, true); + ArraySetAsSeries(smHKBars, true); + ArraySetAsSeries(ichTenkanSens, true); + ArraySetAsSeries(ichKijunSens, true); + ArraySetAsSeries(ichChikouSpans, true); + ArraySetAsSeries(ichSenkouSpanAs, true); + ArraySetAsSeries(ichSenkouSpanBs, true); + ArraySetAsSeries(mcFasts, true); + ArraySetAsSeries(mcSlows, true); + ArraySetAsSeries(mcVerifiers, true); + ArraySetAsSeries(strTrends, true); + ArraySetAsSeries(strStates, true); + ArraySetAsSeries(cheLongExit1s, true); + ArraySetAsSeries(cheLongExit2s, true); + ArraySetAsSeries(cheShortExit1s, true); + ArraySetAsSeries(cheShortExit2s, true); + ArraySetAsSeries(oscAtrs, true); + ArraySetAsSeries(oscRviMains, true); + ArraySetAsSeries(oscRviSignals, true); + ArraySetAsSeries(oscBullPs, true); + ArraySetAsSeries(oscBearPs, true); + ArraySetAsSeries(oscVolumes, true); + ArraySetAsSeries(oscRsis, true); + ArraySetAsSeries(oscCcis, true); + ArraySetAsSeries(oscMomentums, true); + ArraySetAsSeries(oscSars, true); + ArraySetAsSeries(oscMacdMains, true); + ArraySetAsSeries(oscMacdSignals, true); + ArraySetAsSeries(oscStochMains, true); + ArraySetAsSeries(oscStochSignals, true); + ArraySetAsSeries(oscStddevs, true); + ArraySetAsSeries(zigzags, true); + ArraySetAsSeries(zigzagPVs, true); + ArraySetAsSeries(mrbFasts, true); + ArraySetAsSeries(mrb1Fasts, true); + ArraySetAsSeries(mrb2Fasts, true); + ArraySetAsSeries(mrb3Fasts, true); + ArraySetAsSeries(mrb4Fasts, true); + ArraySetAsSeries(mrb5Fasts, true); + ArraySetAsSeries(mrb6Fasts, true); + ArraySetAsSeries(mrbSlows, true); + ArraySetAsSeries(mrb1Slows, true); + ArraySetAsSeries(mrb2Slows, true); + ArraySetAsSeries(mrb3Slows, true); + ArraySetAsSeries(mrb4Slows, true); + ArraySetAsSeries(mrb5Slows, true); + ArraySetAsSeries(mrb6Slows, true); + ArraySetAsSeries(donUpperOs, true); + ArraySetAsSeries(donLowerOs, true); + ArraySetAsSeries(donUpperCs, true); + ArraySetAsSeries(donLowerCs, true); + ArraySetAsSeries(donUpperHs, true); + ArraySetAsSeries(donLowerHs, true); + ArraySetAsSeries(donUpperLs, true); + ArraySetAsSeries(donLowerLs, true); + ArraySetAsSeries(pvPeaks, true); + ArraySetAsSeries(pvVales, true); + ArraySetAsSeries(pvResistances, true); + ArraySetAsSeries(pvSupports, true); + ArraySetAsSeries(pvFib1s, true); + ArraySetAsSeries(pvFib2s, true); + ArraySetAsSeries(pvFib3s, true); + ArraySetAsSeries(pvFib4s, true); + ArraySetAsSeries(pvFib5s, true); + ArraySetAsSeries(pvSCHHs, true); + ArraySetAsSeries(pvSCLLs, true); + ArraySetAsSeries(pvMCHHs, true); + ArraySetAsSeries(pvMCLLs, true); + ArraySetAsSeries(pvLCHHs, true); + ArraySetAsSeries(pvLCLLs, true); + ArraySetAsSeries(pvHCHHs, true); + ArraySetAsSeries(pvHCLLs, true); + + // + isHKBullish = false; + isSMHKBullish = false; + isHKBearish = false; + isSMHKBearish = false; + isClosedOverSMHK = false; + isClosedUnderSMHK = false; + isHKBullishPrev = false; + isSMHKBullishPrev = false; + isHKBearishPrev = false; + isSMHKBearishPrev = false; + isClosedOverSMHKPrev = false; + isClosedUnderSMHKPrev = false; + isZigZagInPeak = false; + isZigZagInVale = false; + isDONAttachedMaxLower = false; + isDONAttachedMinLower = false; + isDONCrossedOverMaxLower = false; + isDONCrossedUnderMaxLower = false; + isDONAttachedMaxUpper = false; + isDONAttachedMinUpper = false; + isDONCrossedOverMaxUpper = false; + isDONCrossedUnderMaxUpper = false; + isPVPeakSameAs = false; + isPVNewPeak = false; + isPVNewPeakOverLast = false; + isPVNewPeakUnderLast = false; + isPVValeSameAs = false; + isPVNewVale = false; + isPVNewValeOverLast = false; + isPVNewValeUnderLast = false; + isPVFiboIncreased = false; + isPVFiboDecreased = false; + isPVFiboSectionChanged = false; + isPVSCBullish = false; + isPVSCHHBullish = false; + isPVSCLLBullish = false; + isPVSCSwitchedToBullish = false; + isPVSCBearish = false; + isPVSCHHBearish = false; + isPVSCLLBearish = false; + isPVSCSwitchedToBearish = false; + isPVMCBullish = false; + isPVMCHHBullish = false; + isPVMCLLBullish = false; + isPVMCSwitchedToBullish = false; + isPVMCBearish = false; + isPVMCHHBearish = false; + isPVMCLLBearish = false; + isPVMCSwitchedToBearish = false; + isPVLCBullish = false; + isPVLCHHBullish = false; + isPVLCLLBullish = false; + isPVLCSwitchedToBullish = false; + isPVLCBearish = false; + isPVLCHHBearish = false; + isPVLCLLBearish = false; + isPVLCSwitchedToBearish = false; + isPVHCBullish = false; + isPVHCHHBullish = false; + isPVHCLLBullish = false; + isPVHCSwitchedToBullish = false; + isPVHCBearish = false; + isPVHCHHBearish = false; + isPVHCLLBearish = false; + isPVHCSwitchedToBearish = false; + + // + // XTSR ... + isTrendBullish = false; + isTrendBearish = false; + isTrendSwitchedToBullish = false; + isTrendSwitchedToBearish = false; + + // + // XCHE ... + isCHEInLong = false; + isCHEInStrongLong = false; + isCHEInShort = false; + isCHEInStrongShort = false; + + // + // XICH ... + isSenkouSpanAOverB = false; + isSenkouSpanAUnderB = false; + isSenkouSpanAOverLast = false; + isSenkouSpanAUnderLast = false; + isFutureSenkouSpanAOverB = false; + isFutureSenkouSpanAUnderB = false; + isFutureSenkouSpanAOverLast = false; + isFutureSenkouSpanAUnderLast = false; + isCloseOverKijunSen = false; + isCloseUnderKijunSen = false; + isTenkanSenOverKijunSen = false; + isTenkanSenUnderKijunSen = false; + + // + // XMC ... + isFastOverSlow = false; + isFastUnderSlow = false; + isFastOverVerifier = false; + isFastUnderVerifier = false; + isSlowOverVerifier = false; + isSlowUnderVerifier = false; + isCloseOverFast = false; + isCloseUnderFast = false; + isCloseOverSlow = false; + isCloseUnderSlow = false; + isCloseOverVerifier = false; + isCloseUnderVerifier = false; + + // + // XOSC ... + + // + // STDDEV ... + isSTDDEVOverAVG = false; + isSTDDEVUnderAVG = false; + isSTDDEVOverLast = false; + isSTDDEVUnderLast = false; + + // + // RVI ... + isRVILongStart = false; + isRVILongStop = false; + isRVIShortStart = false; + isRVIShortStop = false; + + // + // RSI ... + isRSIUnder50 = false; + isRSIOver70 = false; + isRSIOver50 = false; + isRSIUnder30 = false; + + // + // BULLPOWER ... + isBullPowerOverLast = false; + isBullPoswerUnderLast = false; + isBullPowerOverZero = false; + isBullPoswerUnderZero = false; + + // + // BEARPOWER ... + isBearPowerOverLast = false; + isBearPoswerUnderLast = false; + isBearPowerOverZero = false; + isBearPoswerUnderZero = false; + + // + // CCI ... + isCCIPositive = false; + isCCINegative = false; + isCCIOverPositiveHundred = false; + isCCIUnderNegativeHundred = false; + + // + // MACD ... + isMACDPositiove = false; + isMACDNegative = false; + isMACDOverSignal = false; + isMACDUnderSignal = false; + + // + // STOCH ... + isStochKOverD = false; + isStochKDUnder50 = false; + isStochKUnderD = false; + isStochKDOver50 = false; + isStochKDUnder20 = false; + isStochKDOver80 = false; + + // + // XMR ... + isMRBFastOverSlow = false; + isMRBFastCrossedOverSlow = false; + isMRBCloseOverFast = false; + isMRBFastUnderSlow = false; + isMRBFastCrossedUnderSlow = false; + isMRBCloseUnderSlow = false; + } + + // + // Generate Score ... + virtual void GenerateScore( + double &bullishScore, // Holds Bullish Score ... + double &bearishScore, // Holds Bearish Score ... + double multiplier = 1 // Score Multiplier ... + ) + { + // + double bullScore = 0; + double bearScore = 0; + + // + if (multiplier <= 0) + { + multiplier = 1; + } + + // + // Candlestic ... + + // + // BULLISH ... + if (isLastBullish) + { + bullScore++; + } + if (isCurrentBullish) + { + bullScore++; + } + if (isCurrentMidLineOverLastUp) + { + bullScore++; + } + if (isCurrentMidLineOverLastHigh) + { + bullScore++; + } + if (isCurrentMidLineOverLastMidLine) + { + bullScore++; + } + + // + // BEARISH ... + if (isLastBearish) + { + bearScore++; + } + if (isCurrentBearish) + { + bearScore++; + } + if (isCurrentMidLineUnderLastLow) + { + bearScore++; + } + if (isCurrentMidLineUnderLastDown) + { + bearScore++; + } + if (isCurrentMidLineUnderLastMidLine) + { + bearScore++; + } + + // + // XTD ... + + // + if (isXTDSignalPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDSignalVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBullishPeak) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDBullishVale) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBearishPeak) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBearishVale) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDBullOverBear) + { + bullScore++; + } + + // + if (isXTDBullUnderBear) + { + bearScore++; + } + + // + if (isXTDSignalOverBear) + { + bullScore++; + } + + // + if (isXTDSignalUnderBear) + { + bearScore++; + } + + // + if (isXTDBullCrossedOverBear) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDBullCrossedUnderBear) + { + // + bullScore--; + bearScore++; + } + + // + if (isXTDSignalCrossedOverBear) + { + // + bullScore++; + bearScore--; + } + + // + if (isXTDSignalCrossedUnderBear) + { + // + bullScore--; + bearScore++; + } + + // + // XHK ... + + // + if (isHKBullish) + { + // + bullScore++; + bearScore--; + } + if (isSMHKBullish) + { + // + bullScore++; + bearScore--; + } + if (isHKBearish) + { + // + bullScore--; + bearScore++; + } + if (isSMHKBearish) + { + // + bullScore--; + bearScore++; + } + if (isClosedOverSMHK) + { + // + bullScore++; + bearScore--; + } + if (isClosedUnderSMHK) + { + // + bullScore--; + bearScore++; + } + + // + if (isHKBullishPrev) + { + // + bullScore += 2; + bearScore--; + } + if (isSMHKBullishPrev) + { + // + bullScore += 2; + bearScore--; + } + if (isHKBearishPrev) + { + // + bullScore--; + bearScore += 2; + } + if (isSMHKBearishPrev) + { + // + bullScore--; + bearScore += 2; + } + if (isClosedOverSMHKPrev) + { + // + bullScore += 2; + bearScore--; + } + if (isClosedUnderSMHKPrev) + { + // + bullScore--; + bearScore += 2; + } + + // + // XZG ... + if (isZigZagInPeak) + { + // + bullScore--; + bearScore++; + } + if (isZigZagInVale) + { + // + bullScore++; + bearScore--; + } + + // + // XDON ... + if (isDONAttachedMaxLower) + { + // + bullScore++; + bearScore--; + } + if (isDONAttachedMinLower) + { + bearScore++; + } + if (isDONCrossedOverMaxLower) + { + // + bullScore++; + bearScore--; + } + if (isDONCrossedUnderMaxLower) + { + // + bullScore--; + bearScore++; + } + if (isDONAttachedMaxUpper) + { + // + bullScore--; + bearScore++; + } + if (isDONAttachedMinUpper) + { + bullScore++; + } + if (isDONCrossedOverMaxUpper) + { + // + bullScore++; + bearScore--; + } + if (isDONCrossedUnderMaxUpper) + { + // + bullScore--; + bearScore++; + } + + // + // XPV ... + if (isPVPeakSameAs) + { + } + if (isPVNewPeak) + { + } + if (isPVNewPeakOverLast) + { + // + bullScore--; + bearScore++; + } + if (isPVNewPeakUnderLast) + { + // + bullScore++; + bearScore--; + } + if (isPVValeSameAs) + { + } + if (isPVNewVale) + { + } + if (isPVNewValeOverLast) + { + // + bullScore--; + bearScore++; + } + if (isPVNewValeUnderLast) + { + // + bullScore++; + bearScore--; + } + if (isPVFiboSectionChanged) + { + // + if (isPVFiboIncreased) + { + // + bullScore++; + bearScore--; + } + if (isPVFiboDecreased) + { + // + bullScore--; + bearScore++; + } + } + + // + if (isPVSCBullish) + { + bullScore++; + } + if (isPVSCHHBullish) + { + bullScore--; + } + if (isPVSCLLBullish) + { + bullScore++; + } + if (isPVSCSwitchedToBullish) + { + // + bullScore++; + bearScore--; + } + if (isPVSCBearish) + { + bearScore++; + } + if (isPVSCHHBearish) + { + bearScore--; + } + if (isPVSCLLBearish) + { + bearScore++; + } + if (isPVSCSwitchedToBearish) + { + // + bullScore--; + bearScore++; + } + if (isPVMCBullish) + { + bullScore++; + } + if (isPVMCHHBullish) + { + bullScore--; + } + if (isPVMCLLBullish) + { + bullScore++; + } + if (isPVMCSwitchedToBullish) + { + // + bullScore++; + bearScore--; + } + if (isPVMCBearish) + { + bullScore++; + } + if (isPVMCHHBearish) + { + bearScore--; + } + if (isPVMCLLBearish) + { + bearScore++; + } + if (isPVMCSwitchedToBearish) + { + // + bullScore--; + bearScore++; + } + if (isPVLCBullish) + { + bullScore++; + } + if (isPVLCHHBullish) + { + bullScore--; + } + if (isPVLCLLBullish) + { + bullScore++; + } + if (isPVLCSwitchedToBullish) + { + // + bullScore++; + bullScore--; + } + if (isPVLCBearish) + { + bearScore++; + } + if (isPVLCHHBearish) + { + bearScore--; + } + if (isPVLCLLBearish) + { + bearScore++; + } + if (isPVLCSwitchedToBearish) + { + // + bullScore--; + bearScore++; + } + if (isPVHCBullish) + { + bullScore++; + } + if (isPVHCHHBullish) + { + bullScore--; + } + if (isPVHCLLBullish) + { + bullScore++; + } + if (isPVHCSwitchedToBullish) + { + // + bullScore++; + bearScore--; + } + if (isPVHCBearish) + { + bearScore++; + } + if (isPVHCHHBearish) + { + bearScore--; + } + if (isPVHCLLBearish) + { + bearScore++; + } + if (isPVHCSwitchedToBearish) + { + // + bullScore--; + bearScore++; + } + + // + // XSTR ... + if (isTrendBullish) + { + bullScore++; + } + if (isTrendBearish) + { + bearScore++; + } + if (isTrendSwitchedToBullish) + { + // + bullScore++; + bearScore--; + } + if (isTrendSwitchedToBearish) + { + // + bullScore--; + bearScore++; + } + + // + // XICH ... + + // + // BULLISH ... + if (isSenkouSpanAOverB) + { + bullScore++; + } + if (isSenkouSpanAOverLast) + { + bullScore++; + } + if (isCloseOverKijunSen) + { + bullScore++; + } + if (isTenkanSenOverKijunSen) + { + bullScore++; + } + if (isFutureSenkouSpanAOverB) + { + bullScore++; + } + if (isFutureSenkouSpanAOverLast) + { + bullScore++; + } + if (isTenkanSenCrossedOverKijunSen) + { + // + bullScore++; + bearScore--; + } + + // + // BEARISH ... + if (isSenkouSpanAUnderB) + { + bearScore++; + } + if (isSenkouSpanAUnderLast) + { + bearScore++; + } + if (isCloseUnderKijunSen) + { + bearScore++; + } + if (isTenkanSenUnderKijunSen) + { + bearScore++; + } + if (isFutureSenkouSpanAUnderB) + { + bearScore++; + } + if (isFutureSenkouSpanAUnderLast) + { + bearScore++; + } + if (isTenkanSenCrossedUnderKijunSen) + { + // + bullScore--; + bearScore++; + } + + // + // XMC ... + + // + // BULLISH ... + if (isFastOverSlow) + { + bullScore++; + } + if (isFastOverVerifier) + { + bullScore++; + } + if (isSlowOverVerifier) + { + bullScore++; + } + if (isCloseOverFast) + { + bullScore++; + } + if (isCloseOverSlow) + { + bullScore++; + } + if (isCloseOverVerifier) + { + bullScore++; + } + if (isFastCrossedOverSlow) + { + // + bullScore++; + bearScore--; + } + if (isFastCrossedOverVerifier) + { + // + bullScore++; + bearScore--; + } + if (isSlowCrossedOverVerifier) + { + // + bullScore++; + bearScore--; + } + + // + // BEARISH ... + if (isFastUnderSlow) + { + bearScore++; + } + if (isFastUnderVerifier) + { + bearScore++; + } + if (isSlowUnderVerifier) + { + bearScore++; + } + if (isCloseUnderFast) + { + bearScore++; + } + if (isCloseUnderSlow) + { + bearScore++; + } + if (isCloseUnderVerifier) + { + bearScore++; + } + if (isFastCrossedUnderSlow) + { + // + bullScore--; + bearScore++; + } + if (isFastCrossedUnderVerifier) + { + // + bullScore--; + bearScore++; + } + if (isSlowCrossedUnderVerifier) + { + // + bullScore--; + bearScore++; + } + + // + // XCHE ... + if (isCHEInLong) + { + bullScore++; + } + if (isCHEInStrongLong) + { + // + bullScore++; + bearScore--; + } + if (isCHESwitchedInStrongLong) + { + // + bullScore++; + bearScore--; + } + if (isCHEInShort) + { + // + bearScore++; + } + if (isCHEInStrongShort) + { + // + bullScore--; + bearScore++; + } + if (isCHESwitchedInStrongShort) + { + // + bullScore--; + bearScore++; + } + + // + // XOSC ... + + // + // STDDEV ... + + // + // BULLISH ... + if (isSTDDEVOverAVG) + { + bullScore++; + } + if (isSTDDEVOverLast) + { + bullScore++; + } + + // + // BEARISH ... + if (isSTDDEVUnderAVG) + { + bearScore++; + } + if (isSTDDEVUnderLast) + { + bearScore++; + } + + // + // RVI ... + if (isRVILongStart && !isRVILongStop) + { + bullScore++; + } + if (isRVIShortStart && isRVIShortStop) + { + bearScore++; + } + + // + // RSI ... + + // + // BULLISH ... + if (isRSIUnder30 || (!isRSIUnder30 && isRSIOver50 && isRSIOver70)) + { + bullScore++; + } + + // + // BEARISH ... + if (isRSIOver70 || (!isRSIOver70 && !isRSIOver50 && isRSIUnder30)) + { + bearScore++; + } + + // + // BULLPOWER ... + + // + // BULLISH ... + if (isBullPowerOverLast) + { + bullScore++; + } + if (isBullPowerOverZero) + { + bullScore++; + } + + // + // BEARISH ... + if (isBullPoswerUnderLast) + { + bearScore++; + } + if (isBullPoswerUnderZero) + { + bearScore++; + } + + // + // BEARPOWER ... + + // + // BULLISH ... + if (isBearPoswerUnderLast) + { + bullScore++; + } + if (isBearPoswerUnderZero) + { + bullScore++; + } + + // + // BEARISH ... + if (isBearPowerOverLast) + { + bearScore++; + } + if (isBearPowerOverZero) + { + bearScore++; + } + + // + // CCI ... + + // + // BULLISH ... + if (isCCIPositive) + { + bullScore++; + } + if (isCCIOverPositiveHundred) + { + bullScore++; + } + + // + // BEARISH ... + if (isCCINegative) + { + bearScore++; + } + if (isCCIUnderNegativeHundred) + { + bearScore++; + } + + // + // MACD ... + + // + // BULLISH ... + if (isMACDPositiove) + { + bullScore++; + } + if (isMACDOverSignal) + { + bullScore++; + } + + // + // BEARISH ... + if (isMACDNegative) + { + bearScore++; + } + if (isMACDUnderSignal) + { + bearScore++; + } + + // + // STOCH ... + + // + // BULLISH ... + if (isStochKOverD) + { + bullScore++; + } + if (isStochKDUnder20) + { + bullScore++; + } + if (isStochKDUnder50) + { + bullScore++; + } + + // + // BEARISH ... + if (isStochKUnderD) + { + bearScore++; + } + if (isStochKDOver50) + { + bearScore++; + } + if (isStochKDOver80) + { + bearScore++; + } + + // + // XMR ... + if (isMRBFastOverSlow) + { + bullScore++; + } + if (isMRBFastCrossedOverSlow) + { + // + bullScore++; + bearScore--; + } + if (isMRBCloseOverFast) + { + // + bullScore++; + bearScore--; + } + if (isMRBFastUnderSlow) + { + bearScore++; + } + if (isMRBFastCrossedUnderSlow) + { + // + bullScore--; + bearScore++; + } + if (isMRBCloseUnderSlow) + { + bullScore--; + bearScore++; + } + + // + bullishScore = bullScore * multiplier; + bearishScore = bearScore * multiplier; + } + + // + // Generate Summary ... + virtual string GenerateSummary( + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + result = GenerateSummaryBody( + onlySummary, + multiplier, + separator, + ignoreFalseConditions + // + ); + + // + // Generating Full Result by Combining parts ... + result = + // + "[" + GetToken() + "]" + separator + + "-----------------------------" + separator + + result + + "" + // + ; + + // + return result; + } + + // + string GenerateSummary( + string provided, // Additional Info about Type, Provider and Symbol + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + result = GenerateSummaryBody( + onlySummary, + multiplier, + separator, + ignoreFalseConditions + // + ); + + // + // Generating Full Result by Combining parts ... + result = + // + "[" + GetToken() + "]" + separator + + provided + separator + + "-----------------------------" + separator + + result + + "" + // + ; + + // + return result; + } + + // + string GenerateSummaryBody( + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + double bullScore = 0; + double bearScore = 0; + GenerateScore( + bullScore, + bearScore, + multiplier // + ); + + // + // Common ... + string commonStr = + // + "Commons: " + separator + + "-----------------------------" + separator + + "Time: " + ToString(TimeCurrent()) + separator + + "-----------" + separator + + "Scores: " + separator + + "-----------" + separator + + "Bullish: " + ToString(bullScore) + separator + + "Bearish: " + ToString(bearScore) + separator + + "-----------------------------" + separator + + // + // TODO: Add Scores Later ... + separator + + "" + // + ; + + // + // Candlestick ... + string candlesticStr = + // + ToString("isLastBullish", isLastBullish, ignoreFalseConditions) + + ToString("isLastBearish", isLastBearish, ignoreFalseConditions) + + ToString("isCurrentBullish", isCurrentBullish, ignoreFalseConditions) + + ToString("isCurrentBearish", isCurrentBearish, ignoreFalseConditions) + + ToString("isCurrentMidLineOverLastHigh", isCurrentMidLineOverLastHigh, ignoreFalseConditions) + + ToString("isCurrentMidLineUnderLastLow", isCurrentMidLineUnderLastLow, ignoreFalseConditions) + + ToString("isCurrentMidLineOverLastUp", isCurrentMidLineOverLastUp, ignoreFalseConditions) + + ToString("isCurrentMidLineUnderLastDown", isCurrentMidLineUnderLastDown, ignoreFalseConditions) + + ToString("isCurrentMidLineOverLastMidLine", isCurrentMidLineOverLastMidLine, ignoreFalseConditions) + + ToString("isCurrentMidLineUnderLastMidLine", isCurrentMidLineUnderLastMidLine, ignoreFalseConditions) + + "" + // + ; + candlesticStr = SetLabel("Candelstick: ", candlesticStr, separator); + + // + // XHK ... + string hkStr = + // + ToString("isHKBullish", isHKBullish, ignoreFalseConditions) + + ToString("isSMHKBullish", isSMHKBullish, ignoreFalseConditions) + + ToString("isHKBearish", isHKBearish, ignoreFalseConditions) + + ToString("isSMHKBearish", isSMHKBearish, ignoreFalseConditions) + + ToString("isClosedOverSMHK", isClosedOverSMHK, ignoreFalseConditions) + + ToString("isClosedUnderSMHK", isClosedUnderSMHK, ignoreFalseConditions) + + ToString("isHKBullishPrev", isHKBullishPrev, ignoreFalseConditions) + + ToString("isSMHKBullishPrev", isSMHKBullishPrev, ignoreFalseConditions) + + ToString("isHKBearishPrev", isHKBearishPrev, ignoreFalseConditions) + + ToString("isSMHKBearishPrev", isSMHKBearishPrev, ignoreFalseConditions) + + ToString("isClosedOverSMHKPrev", isClosedOverSMHKPrev, ignoreFalseConditions) + + ToString("isClosedUnderSMHKPrev", isClosedUnderSMHKPrev, ignoreFalseConditions) + + "" + // + ; + hkStr = SetLabel("XHK: ", hkStr, separator); + + // + // XZG ... + string zigzagStr = + // + ToString("isZigZagInPeak", isZigZagInPeak, ignoreFalseConditions) + + ToString("isZigZagInVale", isZigZagInVale, ignoreFalseConditions) + + "" + // + ; + zigzagStr = SetLabel("XZG: ", zigzagStr, separator); + + // + // XTD ... + string tdStr = + // + ToString("isXTDSignalPeak", isXTDSignalPeak, ignoreFalseConditions) + + ToString("isXTDSignalVale", isXTDSignalVale, ignoreFalseConditions) + + ToString("isXTDBullishPeak", isXTDBullishPeak, ignoreFalseConditions) + + ToString("isXTDBullishVale", isXTDBullishVale, ignoreFalseConditions) + + ToString("isXTDBearishPeak", isXTDBearishPeak, ignoreFalseConditions) + + ToString("isXTDBearishVale", isXTDBearishVale, ignoreFalseConditions) + + ToString("isXTDBullOverBear", isXTDBullOverBear, ignoreFalseConditions) + + ToString("isXTDBullUnderBear", isXTDBullUnderBear, ignoreFalseConditions) + + ToString("isXTDSignalOverBear", isXTDSignalOverBear, ignoreFalseConditions) + + ToString("isXTDSignalUnderBear", isXTDSignalUnderBear, ignoreFalseConditions) + + ToString("isXTDBullCrossedOverBear", isXTDBullCrossedOverBear, ignoreFalseConditions) + + ToString("isXTDBullCrossedUnderBear", isXTDBullCrossedUnderBear, ignoreFalseConditions) + + ToString("isXTDSignalCrossedOverBear", isXTDSignalCrossedOverBear, ignoreFalseConditions) + + ToString("isXTDSignalCrossedUnderBear", isXTDSignalCrossedUnderBear, ignoreFalseConditions) + + "" + // + ; + tdStr = SetLabel("XTD: ", tdStr, separator); + + // + // XMR ... + string mrbStr = + // + ToString("isMRBFastOverSlow", isMRBFastOverSlow, ignoreFalseConditions) + + ToString("isMRBFastCrossedOverSlow", isMRBFastCrossedOverSlow, ignoreFalseConditions) + + ToString("isMRBCloseOverFast", isMRBCloseOverFast, ignoreFalseConditions) + + ToString("isMRBFastUnderSlow", isMRBFastUnderSlow, ignoreFalseConditions) + + ToString("isMRBFastCrossedUnderSlow", isMRBFastCrossedUnderSlow, ignoreFalseConditions) + + ToString("isMRBCloseUnderSlow", isMRBCloseUnderSlow, ignoreFalseConditions) + + "" + // + ; + mrbStr = SetLabel("XMRB: ", mrbStr, separator); + + // + // XSTR ... + string strStr = + // + ToString("isTrendBullish", isTrendBullish, ignoreFalseConditions) + + ToString("isTrendBearish", isTrendBearish, ignoreFalseConditions) + + ToString("isTrendSwitchedToBullish", isTrendSwitchedToBullish, ignoreFalseConditions) + + ToString("isTrendSwitchedToBearish", isTrendSwitchedToBearish, ignoreFalseConditions) + + "" + // + ; + strStr = SetLabel("XSTR: ", strStr, separator); + + // + // XCHE ... + string cheStr = + // + ToString("isCHEInLong", isCHEInLong, ignoreFalseConditions) + + ToString("isCHEInStrongLong", isCHEInStrongLong, ignoreFalseConditions) + + ToString("isCHESwitchedInStrongLong", isCHESwitchedInStrongLong, ignoreFalseConditions) + + ToString("isCHEInShort", isCHEInShort, ignoreFalseConditions) + + ToString("isCHEInStrongShort", isCHEInStrongShort, ignoreFalseConditions) + + ToString("isCHESwitchedInStrongShort", isCHESwitchedInStrongShort, ignoreFalseConditions) + + "" + // + ; + cheStr = SetLabel("XCHE: ", cheStr, separator); + + // + // XDON ... + string donStr = + // + ToString("isDONAttachedMaxLower", isDONAttachedMaxLower, ignoreFalseConditions) + + ToString("isDONAttachedMinLower", isDONAttachedMinLower, ignoreFalseConditions) + + ToString("isDONCrossedOverMaxLower", isDONCrossedOverMaxLower, ignoreFalseConditions) + + ToString("isDONCrossedUnderMaxLower", isDONCrossedUnderMaxLower, ignoreFalseConditions) + + ToString("isDONAttachedMaxUpper", isDONAttachedMaxUpper, ignoreFalseConditions) + + ToString("isDONAttachedMinUpper", isDONAttachedMinUpper, ignoreFalseConditions) + + ToString("isDONCrossedOverMaxUpper", isDONCrossedOverMaxUpper, ignoreFalseConditions) + + ToString("isDONCrossedUnderMaxUpper", isDONCrossedUnderMaxUpper, ignoreFalseConditions) + + "" + // + ; + donStr = SetLabel("XDON: ", donStr, separator); + + // + // XICH ... + string ichStr = + // + ToString("isSenkouSpanAOverB", isSenkouSpanAOverB, ignoreFalseConditions) + + ToString("isSenkouSpanAUnderB", isSenkouSpanAUnderB, ignoreFalseConditions) + + ToString("isSenkouSpanAOverLast", isSenkouSpanAOverLast, ignoreFalseConditions) + + ToString("isSenkouSpanAUnderLast", isSenkouSpanAUnderLast, ignoreFalseConditions) + + ToString("isCloseOverKijunSen", isCloseOverKijunSen, ignoreFalseConditions) + + ToString("isCloseUnderKijunSen", isCloseUnderKijunSen, ignoreFalseConditions) + + ToString("isTenkanSenOverKijunSen", isTenkanSenOverKijunSen, ignoreFalseConditions) + + ToString("isTenkanSenUnderKijunSen", isTenkanSenUnderKijunSen, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAOverB", isFutureSenkouSpanAOverB, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAUnderB", isFutureSenkouSpanAUnderB, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAOverLast", isFutureSenkouSpanAOverLast, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAUnderLast", isFutureSenkouSpanAUnderLast, ignoreFalseConditions) + + "" + // + ; + ichStr = SetLabel("XICH: ", ichStr, separator); + + // + // XMC ... + string mcStr = + // + ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions) + + ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions) + + ToString("isFastOverVerifier", isFastOverVerifier, ignoreFalseConditions) + + ToString("isFastUnderVerifier", isFastUnderVerifier, ignoreFalseConditions) + + ToString("isSlowOverVerifier", isSlowOverVerifier, ignoreFalseConditions) + + ToString("isSlowUnderVerifier", isSlowUnderVerifier, ignoreFalseConditions) + + ToString("isCloseOverFast", isCloseOverFast, ignoreFalseConditions) + + ToString("isCloseUnderFast", isCloseUnderFast, ignoreFalseConditions) + + ToString("isCloseOverSlow", isCloseOverSlow, ignoreFalseConditions) + + ToString("isCloseUnderSlow", isCloseUnderSlow, ignoreFalseConditions) + + ToString("isCloseOverVerifier", isCloseOverVerifier, ignoreFalseConditions) + + ToString("isCloseUnderVerifier", isCloseUnderVerifier, ignoreFalseConditions) + + ToString("isFastCrossedOverSlow", isFastCrossedOverSlow, ignoreFalseConditions) + + ToString("isFastCrossedUnderSlow", isFastCrossedUnderSlow, ignoreFalseConditions) + + ToString("isFastCrossedOverVerifier", isFastCrossedOverVerifier, ignoreFalseConditions) + + ToString("isFastCrossedUnderVerifier", isFastCrossedUnderVerifier, ignoreFalseConditions) + + ToString("isSlowCrossedOverVerifier", isSlowCrossedOverVerifier, ignoreFalseConditions) + + ToString("isSlowCrossedUnderVerifier", isSlowCrossedUnderVerifier, ignoreFalseConditions) + + "" + // + ; + mcStr = SetLabel("XMC: ", mcStr, separator); + + // + // XPV ... + string pvStr = + // + ToString("isPVPeakSameAs", isPVPeakSameAs, ignoreFalseConditions) + + ToString("isPVNewPeak", isPVNewPeak, ignoreFalseConditions) + + ToString("isPVNewPeakOverLast", isPVNewPeakOverLast, ignoreFalseConditions) + + ToString("isPVNewPeakUnderLast", isPVNewPeakUnderLast, ignoreFalseConditions) + + ToString("isPVValeSameAs", isPVValeSameAs, ignoreFalseConditions) + + ToString("isPVNewVale", isPVNewVale, ignoreFalseConditions) + + ToString("isPVNewValeOverLast", isPVNewValeOverLast, ignoreFalseConditions) + + ToString("isPVNewValeUnderLast", isPVNewValeUnderLast, ignoreFalseConditions) + + ToString("isPVFiboIncreased", isPVFiboIncreased, ignoreFalseConditions) + + ToString("isPVFiboDecreased", isPVFiboDecreased, ignoreFalseConditions) + + ToString("isPVFiboSectionChanged", isPVFiboSectionChanged, ignoreFalseConditions) + + ToString("isPVSCBullish", isPVSCBullish, ignoreFalseConditions) + + ToString("isPVSCHHBullish", isPVSCHHBullish, ignoreFalseConditions) + + ToString("isPVSCLLBullish", isPVSCLLBullish, ignoreFalseConditions) + + ToString("isPVSCSwitchedToBullish", isPVSCSwitchedToBullish, ignoreFalseConditions) + + ToString("isPVSCBearish", isPVSCBearish, ignoreFalseConditions) + + ToString("isPVSCHHBearish", isPVSCHHBearish, ignoreFalseConditions) + + ToString("isPVSCLLBearish", isPVSCLLBearish, ignoreFalseConditions) + + ToString("isPVSCSwitchedToBearish", isPVSCSwitchedToBearish, ignoreFalseConditions) + + ToString("isPVMCBullish", isPVMCBullish, ignoreFalseConditions) + + ToString("isPVMCHHBullish", isPVMCHHBullish, ignoreFalseConditions) + + ToString("isPVMCLLBullish", isPVMCLLBullish, ignoreFalseConditions) + + ToString("isPVMCSwitchedToBullish", isPVMCSwitchedToBullish, ignoreFalseConditions) + + ToString("isPVMCBearish", isPVMCBearish, ignoreFalseConditions) + + ToString("isPVMCHHBearish", isPVMCHHBearish, ignoreFalseConditions) + + ToString("isPVMCLLBearish", isPVMCLLBearish, ignoreFalseConditions) + + ToString("isPVMCSwitchedToBearish", isPVMCSwitchedToBearish, ignoreFalseConditions) + + ToString("isPVLCBullish", isPVLCBullish, ignoreFalseConditions) + + ToString("isPVLCHHBullish", isPVLCHHBullish, ignoreFalseConditions) + + ToString("isPVLCLLBullish", isPVLCLLBullish, ignoreFalseConditions) + + ToString("isPVLCSwitchedToBullish", isPVLCSwitchedToBullish, ignoreFalseConditions) + + ToString("isPVLCBearish", isPVLCBearish, ignoreFalseConditions) + + ToString("isPVLCHHBearish", isPVLCHHBearish, ignoreFalseConditions) + + ToString("isPVLCLLBearish", isPVLCLLBearish, ignoreFalseConditions) + + ToString("isPVLCSwitchedToBearish", isPVLCSwitchedToBearish, ignoreFalseConditions) + + ToString("isPVHCBullish", isPVHCBullish, ignoreFalseConditions) + + ToString("isPVHCHHBullish", isPVHCHHBullish, ignoreFalseConditions) + + ToString("isPVHCLLBullish", isPVHCLLBullish, ignoreFalseConditions) + + ToString("isPVHCSwitchedToBullish", isPVHCSwitchedToBullish, ignoreFalseConditions) + + ToString("isPVHCBearish", isPVHCBearish, ignoreFalseConditions) + + ToString("isPVHCHHBearish", isPVHCHHBearish, ignoreFalseConditions) + + ToString("isPVHCLLBearish", isPVHCLLBearish, ignoreFalseConditions) + + ToString("isPVHCSwitchedToBearish", isPVHCSwitchedToBearish, ignoreFalseConditions) + + "" + // + ; + pvStr = SetLabel("XPV: ", pvStr, separator); + + // + // XOSC ... + + // + // STDDEV ... + string stddevStr = + // + ToString("isSTDDEVOverAVG", isSTDDEVOverAVG, ignoreFalseConditions) + + ToString("isSTDDEVUnderAVG", isSTDDEVUnderAVG, ignoreFalseConditions) + + ToString("isSTDDEVOverLast", isSTDDEVOverLast, ignoreFalseConditions) + + ToString("isSTDDEVUnderLast", isSTDDEVUnderLast, ignoreFalseConditions) + + "" + // + ; + stddevStr = SetLabel("STDDEV: ", stddevStr, separator); + + // + // RVI ... + string rviStr = + // + ToString("isRVILongStart", isRVILongStart, ignoreFalseConditions) + + ToString("isRVILongStop", isRVILongStop, ignoreFalseConditions) + + ToString("isRVIShortStart", isRVIShortStart, ignoreFalseConditions) + + ToString("isRVIShortStop", isRVIShortStop, ignoreFalseConditions) + + "" + // + ; + rviStr = SetLabel("RVI: ", rviStr, separator); + + // + // RSI ... + string rsiStr = + // + ToString("isRSIOver50", isRSIOver50, ignoreFalseConditions) + + ToString("isRSIUnder50", isRSIUnder50, ignoreFalseConditions) + + ToString("isRSIOver70", isRSIOver70, ignoreFalseConditions) + + ToString("isRSIUnder30", isRSIUnder30, ignoreFalseConditions) + + "" + // + ; + rsiStr = SetLabel("RSI: ", rsiStr, separator); + + // + // CCI ... + string cciStr = + // + ToString("isCCIPositive", isCCIPositive, ignoreFalseConditions) + + ToString("isCCINegative", isCCINegative, ignoreFalseConditions) + + ToString("isCCIOverPositiveHundred", isCCIOverPositiveHundred, ignoreFalseConditions) + + ToString("isCCIUnderNegativeHundred", isCCIUnderNegativeHundred, ignoreFalseConditions) + + "" + // + ; + cciStr = SetLabel("CCI: ", cciStr, separator); + + // + // MACD ... + string macdStr = + // + ToString("isMACDPositiove", isMACDPositiove, ignoreFalseConditions) + + ToString("isMACDNegative", isMACDNegative, ignoreFalseConditions) + + ToString("isMACDOverSignal", isMACDOverSignal, ignoreFalseConditions) + + ToString("isMACDUnderSignal", isMACDUnderSignal, ignoreFalseConditions) + + "" + // + ; + macdStr = SetLabel("MACD: ", macdStr, separator); + + // + // BULLP ... + string bullPStr = + // + ToString("isBullPowerOverLast", isBullPowerOverLast, ignoreFalseConditions) + + ToString("isBullPoswerUnderLast", isBullPoswerUnderLast, ignoreFalseConditions) + + ToString("isBullPowerOverZero", isBullPowerOverZero, ignoreFalseConditions) + + ToString("isBullPoswerUnderZero", isBullPoswerUnderZero, ignoreFalseConditions) + + "" + // + ; + bullPStr = SetLabel("BULLP: ", bullPStr, separator); + + // + // BEARP ... + string bearPStr = + // + ToString("isBearPowerOverLast", isBearPowerOverLast, ignoreFalseConditions) + + ToString("isBearPoswerUnderLast", isBearPoswerUnderLast, ignoreFalseConditions) + + ToString("isBearPowerOverZero", isBearPowerOverZero, ignoreFalseConditions) + + ToString("isBearPoswerUnderZero", isBearPoswerUnderZero, ignoreFalseConditions) + + "" + // + ; + bearPStr = SetLabel("BEARP: ", bearPStr, separator); + + // + // STOCH ... + string stochStr = + // + ToString("isStochKOverD", isStochKOverD, ignoreFalseConditions) + + ToString("isStochKUnderD", isStochKUnderD, ignoreFalseConditions) + + ToString("isStochKDOver50", isStochKDOver50, ignoreFalseConditions) + + ToString("isStochKDOver80", isStochKDOver80, ignoreFalseConditions) + + ToString("isStochKDUnder20", isStochKDUnder20, ignoreFalseConditions) + + ToString("isStochKDUnder50", isStochKDUnder50, ignoreFalseConditions) + + "" + // + ; + stochStr = SetLabel("STOCH: ", stochStr, separator); + + // + string oscStr = + // + stddevStr + + rviStr + + rsiStr + + cciStr + + macdStr + + bullPStr + + bearPStr + + stochStr + + "" + // + ; + oscStr = SetLabel("XOSC: ", oscStr, separator); + + // + result = + // + commonStr + + candlesticStr + + (onlySummary + ? "" + : hkStr + + tdStr + + zigzagStr + + mrbStr + + strStr + + cheStr + + donStr + + ichStr + + mcStr + + pvStr + + oscStr + + "" // + ) + + "" + // + ; + + // + return result; + } + + // + string GetTitle() + { + // + string result = NULL; + + // + result = + // + "[" + ToString(cycle) + "]: " + ToString(period) + // + ; + + // + return result; + } + + // + // For Data Collector ... + string GetToken() + { + return GetSpecificToken(this); + } + bool IsModelValid() + { + return false; + } + string ToModelString() + { + return NULL; + } + bool ParseModel(string content) + { + return false; + } + int FindIndex(X121MCycleConditions &items[]) + { + return -1; + } +}; + +// +// Market Class ... +class XSCX121Market : XSCBase +{ + // + // Public ... +public: + // + // Props ... + XSCXHKHelper hk; + XSCXMCHelper mc; + XSCXPVHelper pv; + XSCXZGHelper zg; + XSCXTDHelper td; + XSCXMRBHelper mrb; + XSCXSTRHelper str; + XSCXCHEHelper che; + XSCXOSCHelper osc; + XSCXICHHelper ich; + XSCXDONHelper don; + + // + // Properties ... + + // + // Retrieve Trading Symbol ... + string GetSymbol() + { + return mInputs.cycle.symbol; + } + + // + // Retrieve Cycle Time Frame ... + ENUM_TIMEFRAMES GetPeriod() + { + return mInputs.cycle.period; + } + + // + // Retrieve Market Host Time Frame ... + ENUM_TIMEFRAMES GetHostPeriod() + { + return mInputs.cycle.hostPeriod; + } + + // + // Count Total Available Bars in Market ... + int CountBars() + { + // + Update(0); + return mInputs.cycle.CountBars(); + } + + // + // Check Market is in new Bar ... + int IsNewBar() + { + // + Update(0); + return mInputs.cycle.IsNewBar(); + } + + // + // Retrieve Current Cycles Specific Bar ... + XOHCL GetBar(int barIndex) + { + // + Update(0); + return mInputs.cycle.GetBar(barIndex); + } + + // + // Retrieve Current Bar Index based on Host Period bar Index ... + int GetBarIndex(int barIndex) + { + // + Update(barIndex); + return mInputs.cycle.GetBarIndex(barIndex); + } + + // + // Retrieve Bar Time ... + datetime GetBarTime(int barIndex) + { + // + Update(0); + return mInputs.cycle.GetBarTime(barIndex); + } + + // + // Retrieve Current Market Config ... + bool GetInputs(X121MCycleInputs &inputs) + { + // + bool result = false; + + // + inputs = mInputs; + + // + result = inputs.IsValid(); + + // + return result; + } + + // + // Set Market Inputs and Re Initial ... + bool SetInputs( + X121MCycleInputs &inputs // Config + ) + { + // + return Init(inputs); + } + + // + // Tools ... + // + void GetMarketConditions( + X121MCycleConditions &conditions, // Market Conditions Result + int barIndex = 0, // Specified Bar Index + int mNumberOfItems = 15 // Number of Reading Items + ) + { + // + conditions.Clear(); + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (barIndex >= CountBars()) + { + barIndex = CountBars() + 2; + } + + // + int curr = barIndex + 1; + int prev = curr + 1; + + // + // Here i Have to Calculate Market Conditions based on + // Several Indicator/Oscillator(s) ... + + // + // Set Commons ... + conditions.time = GetBarTime(barIndex); + conditions.cycle = mInputs.cycle.cycle; + conditions.prefix = mInputs.cycle.prefix; + conditions.symbol = mInputs.cycle.symbol; + conditions.period = mInputs.cycle.period; + conditions.hostPeriod = mInputs.cycle.hostPeriod; + + // + Clean(conditions.bars); + GetBars( + conditions.bars, + conditions.symbol, + conditions.period, + barIndex, + barIndex + 5); + + // + XOHCL cBar = GetBar(barIndex); + XOHCL pBar = GetBar(barIndex + 1); + + // + // CANDELSTICK ... + + // + bool isLastBullish = + // + pBar.IsBullish() + // + ; + + // + bool isLastBearish = + // + pBar.IsBearish() + // + ; + + // + bool isCurrentBullish = + // + cBar.IsBullish() + // + ; + + // + bool isCurrentBearish = + // + cBar.IsBearish() + // + ; + + // + bool isCurrentMidLineOverLastHigh = + // + cBar.GetMid() > pBar.high; + // + ; + + // + bool isCurrentMidLineUnderLastLow = + // + cBar.GetMid() < pBar.low + // + ; + + // + bool isCurrentMidLineOverLastUp = + // + cBar.GetMid() > pBar.GetUp() + // + ; + + // + bool isCurrentMidLineUnderLastDown = + // + cBar.GetMid() < pBar.GetDown() + // + ; + + // + bool isCurrentMidLineOverLastMidLine = + // + cBar.GetMid() > pBar.GetMid() + // + ; + + // + bool isCurrentMidLineUnderLastMidLine = + // + cBar.GetMid() < pBar.GetMid() + // + ; + + // + conditions.isLastBullish = isLastBullish; + conditions.isLastBearish = isLastBearish; + conditions.isCurrentBullish = isCurrentBullish; + conditions.isCurrentBearish = isCurrentBearish; + conditions.isCurrentMidLineOverLastHigh = isCurrentMidLineOverLastHigh; + conditions.isCurrentMidLineUnderLastLow = isCurrentMidLineUnderLastLow; + conditions.isCurrentMidLineOverLastUp = isCurrentMidLineOverLastUp; + conditions.isCurrentMidLineUnderLastDown = isCurrentMidLineUnderLastDown; + conditions.isCurrentMidLineOverLastMidLine = isCurrentMidLineOverLastMidLine; + conditions.isCurrentMidLineUnderLastMidLine = isCurrentMidLineUnderLastMidLine; + + // + // XHK ... + + // + hk.CopyAsOHCL( + barIndex, + mNumberOfItems, + conditions.hkBars // + ); + + // + hk.CopySMAsOHCL( + barIndex, + mNumberOfItems, + conditions.smHKBars // + ); + + // + bool isHKBullish = conditions.hkBars[curr].IsBullish(); + bool isHKBullishPrev = conditions.hkBars[prev].IsBullish(); + bool isSMHKBullish = conditions.smHKBars[curr].IsBullish(); + bool isSMHKBullishPrev = conditions.smHKBars[prev].IsBullish(); + + // + bool isHKBearish = conditions.hkBars[curr].IsBearish(); + bool isHKBearishPrev = conditions.hkBars[prev].IsBearish(); + bool isSMHKBearish = conditions.smHKBars[curr].IsBearish(); + bool isSMHKBearishPrev = conditions.smHKBars[prev].IsBearish(); + + // + bool isClosedOverSMHK = conditions.bars[curr].close > conditions.smHKBars[curr].GetUp(); + bool isClosedUnderSMHK = conditions.bars[curr].close < conditions.smHKBars[curr].GetDown(); + bool isClosedOverSMHKPrev = conditions.bars[prev].close > conditions.smHKBars[prev].GetUp(); + bool isClosedUnderSMHKPrev = conditions.bars[prev].close < conditions.smHKBars[prev].GetDown(); + + // + conditions.isHKBullish = isHKBullish; + conditions.isSMHKBullish = isSMHKBullish; + conditions.isHKBearish = isHKBearish; + conditions.isSMHKBearish = isSMHKBearish; + conditions.isClosedOverSMHK = isClosedOverSMHK; + conditions.isClosedUnderSMHK = isClosedUnderSMHK; + conditions.isHKBullishPrev = isHKBullishPrev; + conditions.isSMHKBullishPrev = isSMHKBullishPrev; + conditions.isHKBearishPrev = isHKBearishPrev; + conditions.isSMHKBearishPrev = isSMHKBearishPrev; + conditions.isClosedOverSMHKPrev = isClosedOverSMHKPrev; + conditions.isClosedUnderSMHKPrev = isClosedUnderSMHKPrev; + + // + // XZG ... + + // + zg.CopyMain( + barIndex, + mNumberOfItems, + conditions.zigzags // + ); + + // + zg.CopyPeaksAndVales( + barIndex, + mNumberOfItems, + conditions.zigzagPVs // + ); + + // + // Looking for Vale ... + bool isZigZagInPeak = conditions.zigzags[curr] < conditions.zigzagPVs[curr]; + conditions.isZigZagInPeak = isZigZagInPeak; + + // + // Looking for Peak ... + bool isZigZagInVale = conditions.zigzags[curr] > conditions.zigzagPVs[curr]; + conditions.isZigZagInVale = isZigZagInVale; + + // + // XMR ... + + // + mrb.CopyFast( + barIndex, + mNumberOfItems, + conditions.mrbFasts // + ); + + // + mrb.CopyR1Fast( + barIndex, + mNumberOfItems, + conditions.mrb1Fasts // + ); + + // + mrb.CopyR2Fast( + barIndex, + mNumberOfItems, + conditions.mrb2Fasts // + ); + + // + mrb.CopyR3Fast( + barIndex, + mNumberOfItems, + conditions.mrb3Fasts // + ); + + // + mrb.CopyR4Fast( + barIndex, + mNumberOfItems, + conditions.mrb4Fasts // + ); + + // + mrb.CopyR5Fast( + barIndex, + mNumberOfItems, + conditions.mrb5Fasts // + ); + + // + mrb.CopyR6Fast( + barIndex, + mNumberOfItems, + conditions.mrb6Fasts // + ); + + // + mrb.CopySlow( + barIndex, + mNumberOfItems, + conditions.mrbSlows // + ); + + // + mrb.CopyR1Slow( + barIndex, + mNumberOfItems, + conditions.mrb1Slows // + ); + + // + mrb.CopyR2Slow( + barIndex, + mNumberOfItems, + conditions.mrb2Slows // + ); + + // + mrb.CopyR3Slow( + barIndex, + mNumberOfItems, + conditions.mrb3Slows // + ); + + // + mrb.CopyR4Slow( + barIndex, + mNumberOfItems, + conditions.mrb4Slows // + ); + + // + mrb.CopyR5Slow( + barIndex, + mNumberOfItems, + conditions.mrb5Slows // + ); + + // + mrb.CopyR6Slow( + barIndex, + mNumberOfItems, + conditions.mrb6Slows // + ); + + // + bool isMRBFastOverSlow = + // + conditions.mrbFasts[curr] > conditions.mrbSlows[curr] && + conditions.mrbFasts[prev] > conditions.mrbSlows[prev] + // + ; + bool isMRBFastCrossedOverSlow = + // + conditions.mrbFasts[curr] > conditions.mrbSlows[curr] && + conditions.mrbFasts[prev] <= conditions.mrbSlows[prev] + // + ; + bool isMRBCloseOverFast = + // + conditions.bars[prev].close > conditions.mrbFasts[prev] && + conditions.bars[curr].low > conditions.mrbFasts[prev] + // + ; + bool isMRBFastUnderSlow = + // + conditions.mrbFasts[curr] < conditions.mrbSlows[curr] && + conditions.mrbFasts[prev] < conditions.mrbSlows[prev] + // + ; + bool isMRBFastCrossedUnderSlow = + // + conditions.mrbFasts[curr] < conditions.mrbSlows[curr] && + conditions.mrbFasts[prev] >= conditions.mrbSlows[prev] + // + ; + bool isMRBCloseUnderSlow = + // + conditions.bars[prev].close < conditions.mrbSlows[prev] && + conditions.bars[curr].high < conditions.mrbSlows[prev] + // + ; + + // + isMRBFastOverSlow = isMRBFastOverSlow; + isMRBFastCrossedOverSlow = isMRBFastCrossedOverSlow; + isMRBCloseOverFast = isMRBCloseOverFast; + isMRBFastUnderSlow = isMRBFastUnderSlow; + isMRBFastCrossedUnderSlow = isMRBFastCrossedUnderSlow; + isMRBCloseUnderSlow = isMRBCloseUnderSlow; + + // + // XDON ... + + // + don.CopyUpperO( + barIndex, + mNumberOfItems, + conditions.donUpperOs // + ); + don.CopyLowerO( + barIndex, + mNumberOfItems, + conditions.donLowerOs // + ); + don.CopyUpperC( + barIndex, + mNumberOfItems, + conditions.donUpperCs // + ); + don.CopyLowerC( + barIndex, + mNumberOfItems, + conditions.donLowerCs // + ); + don.CopyUpperH( + barIndex, + mNumberOfItems, + conditions.donUpperHs // + ); + don.CopyLowerH( + barIndex, + mNumberOfItems, + conditions.donLowerHs // + ); + don.CopyUpperL( + barIndex, + mNumberOfItems, + conditions.donUpperLs // + ); + don.CopyLowerL( + barIndex, + mNumberOfItems, + conditions.donLowerLs // + ); + + // + // Upper ... + + // + double donUpperO = conditions.donUpperOs[curr]; + double donUpperOPrev = conditions.donUpperOs[prev]; + + // + double donUpperC = conditions.donUpperCs[curr]; + double donUpperCPrev = conditions.donUpperCs[prev]; + + // + double donUpperH = conditions.donUpperHs[curr]; + double donUpperHPrev = conditions.donUpperHs[prev]; + + // + double donUpperL = conditions.donUpperLs[curr]; + double donUpperLPrev = conditions.donUpperLs[prev]; + + // + double donUppers[] = { + donUpperO, + donUpperC, + donUpperH, + donUpperL // + }; + double maxDonUpper = GetMax(donUppers); + double minDonUpper = GetMin(donUppers); + + // + double donUpperPrevs[] = { + donUpperOPrev, + donUpperCPrev, + donUpperHPrev, + donUpperLPrev // + }; + double maxDonUpperPrev = GetMax(donUpperPrevs); + double minDonUpperPrev = GetMin(donUpperPrevs); + + // + // Lower ... + + // + double donLowerO = conditions.donLowerOs[curr]; + double donLowerOPrev = conditions.donLowerOs[prev]; + + // + double donLowerC = conditions.donLowerCs[curr]; + double donLowerCPrev = conditions.donLowerCs[prev]; + + // + double donLowerH = conditions.donLowerHs[curr]; + double donLowerHPrev = conditions.donLowerHs[prev]; + + // + double donLowerL = conditions.donLowerLs[curr]; + double donLowerLPrev = conditions.donLowerLs[prev]; + + // + double donLowers[] = { + donLowerO, + donLowerC, + donLowerH, + donLowerL // + }; + double maxDonLower = GetMax(donLowers); + double minDonLower = GetMin(donLowers); + + // + double donLowerPrevs[] = { + donLowerOPrev, + donLowerCPrev, + donLowerHPrev, + donLowerLPrev // + }; + double maxDonLowerPrev = GetMax(donLowerPrevs); + double minDonLowerPrev = GetMin(donLowerPrevs); + + // + bool isDONAttachedMaxLower = conditions.bars[curr].low == maxDonLower; + bool isDONAttachedMinLower = conditions.bars[curr].low == minDonLower; + bool isDONCrossedOverMaxLower = + // + ((conditions.bars[curr].low > maxDonLower) || + (conditions.bars[curr].close > maxDonLower)) + // + && + // + ((conditions.bars[prev].high <= maxDonLower) || + (conditions.bars[prev].open <= maxDonLower)) + // + ; + bool isDONCrossedUnderMaxLower = + // + ((conditions.bars[curr].low < maxDonLower) || + (conditions.bars[curr].close < maxDonLower)) + // + && + // + ((conditions.bars[prev].high >= maxDonLower) || + (conditions.bars[prev].open >= maxDonLower)) + // + ; + + // + bool isDONAttachedMaxUpper = conditions.bars[curr].high == maxDonUpper; + bool isDONAttachedMinUpper = conditions.bars[curr].high == minDonUpper; + bool isDONCrossedOverMaxUpper = + // + ((conditions.bars[curr].low > maxDonUpper) || + (conditions.bars[curr].close > maxDonUpper)) + // + && + // + ((conditions.bars[prev].high <= maxDonUpper) || + (conditions.bars[prev].open <= maxDonUpper)) + // + ; + bool isDONCrossedUnderMaxUpper = + // + ((conditions.bars[curr].low < maxDonUpper) || + (conditions.bars[curr].close < maxDonUpper)) + // + && + // + ((conditions.bars[prev].high >= maxDonUpper) || + (conditions.bars[prev].open >= maxDonUpper)) + // + ; + + // + conditions.isDONAttachedMaxLower = isDONAttachedMaxLower; + conditions.isDONAttachedMinLower = isDONAttachedMinLower; + conditions.isDONCrossedOverMaxLower = isDONCrossedOverMaxLower; + conditions.isDONCrossedUnderMaxLower = isDONCrossedUnderMaxLower; + + // + conditions.isDONAttachedMaxUpper = isDONAttachedMaxUpper; + conditions.isDONAttachedMinUpper = isDONAttachedMinUpper; + conditions.isDONCrossedOverMaxUpper = isDONCrossedOverMaxUpper; + conditions.isDONCrossedUnderMaxUpper = isDONCrossedUnderMaxUpper; + + // + // XPV ... + + // + pv.CopyPeak( + barIndex, + mNumberOfItems, + conditions.pvPeaks // + ); + pv.CopyVale( + barIndex, + mNumberOfItems, + conditions.pvVales // + ); + pv.CopyResistance( + barIndex, + mNumberOfItems, + conditions.pvResistances // + ); + pv.CopySupport( + barIndex, + mNumberOfItems, + conditions.pvSupports // + ); + pv.CopyFib1( + barIndex, + mNumberOfItems, + conditions.pvFib1s // + ); + pv.CopyFib2( + barIndex, + mNumberOfItems, + conditions.pvFib2s // + ); + pv.CopyFib3( + barIndex, + mNumberOfItems, + conditions.pvFib3s // + ); + pv.CopyFib4( + barIndex, + mNumberOfItems, + conditions.pvFib4s // + ); + pv.CopyFib5( + barIndex, + mNumberOfItems, + conditions.pvFib5s // + ); + pv.CopySCHH( + barIndex, + mNumberOfItems, + conditions.pvSCHHs // + ); + pv.CopySCLL( + barIndex, + mNumberOfItems, + conditions.pvSCLLs // + ); + pv.CopyMCHH( + barIndex, + mNumberOfItems, + conditions.pvMCHHs // + ); + pv.CopyMCLL( + barIndex, + mNumberOfItems, + conditions.pvMCLLs // + ); + pv.CopyLCHH( + barIndex, + mNumberOfItems, + conditions.pvLCHHs // + ); + pv.CopyLCLL( + barIndex, + mNumberOfItems, + conditions.pvLCLLs // + ); + pv.CopyHCHH( + barIndex, + mNumberOfItems, + conditions.pvHCHHs // + ); + pv.CopyHCLL( + barIndex, + mNumberOfItems, + conditions.pvHCLLs // + ); + + // + double pvPeak = conditions.pvPeaks[curr]; + double pvPeakPrev = conditions.pvPeaks[prev]; + + // + double pvVale = conditions.pvVales[curr]; + double pvValePrev = conditions.pvVales[prev]; + + // + double pvFib1 = conditions.pvFib1s[curr]; + double pvFib2 = conditions.pvFib2s[curr]; + double pvFib3 = conditions.pvFib3s[curr]; + double pvFib4 = conditions.pvFib4s[curr]; + double pvFib5 = conditions.pvFib5s[curr]; + + // + double pvFib1Prev = conditions.pvFib1s[prev]; + double pvFib2Prev = conditions.pvFib2s[prev]; + double pvFib3Prev = conditions.pvFib3s[prev]; + double pvFib4Prev = conditions.pvFib4s[prev]; + double pvFib5Prev = conditions.pvFib5s[prev]; + + // + bool isPVPeakSameAs = IsSame(conditions.pvPeaks); + bool isPVNewPeak = NotEmpty(pvPeak) && pvPeak != pvPeakPrev; + bool isPVNewPeakOverLast = isPVNewPeak && pvPeak > pvPeakPrev; + bool isPVNewPeakUnderLast = isPVNewPeak && pvPeak < pvPeakPrev; + bool isPVValeSameAs = IsSame(conditions.pvVales); + bool isPVNewVale = NotEmpty(pvVale) && pvVale != pvValePrev; + bool isPVNewValeOverLast = isPVNewVale && pvVale > pvValePrev; + bool isPVNewValeUnderLast = isPVNewVale && pvVale < pvValePrev; + bool isPVFiboIncreased = + // + pvFib1 > pvFib1Prev && + pvFib2 > pvFib2Prev && + pvFib3 > pvFib3Prev && + pvFib4 > pvFib4Prev && + pvFib5 > pvFib5Prev + // + ; + bool isPVFiboDecreased = + // + pvFib1 < pvFib1Prev && + pvFib2 < pvFib2Prev && + pvFib3 < pvFib3Prev && + pvFib4 < pvFib4Prev && + pvFib5 < pvFib5Prev + // + ; + + bool isPVFiboSectionChanged = + // + (isPVNewPeakUnderLast && isPVFiboDecreased) + // + || + // + (isPVNewValeOverLast && isPVFiboIncreased) + // + ; + + // + conditions.isPVPeakSameAs = isPVPeakSameAs; + conditions.isPVNewPeak = isPVNewPeak; + conditions.isPVNewPeakOverLast = isPVNewPeakOverLast; + conditions.isPVNewPeakUnderLast = isPVNewPeakUnderLast; + conditions.isPVValeSameAs = isPVValeSameAs; + conditions.isPVNewVale = isPVNewVale; + conditions.isPVNewValeOverLast = isPVNewValeOverLast; + conditions.isPVNewValeUnderLast = isPVNewValeUnderLast; + conditions.isPVFiboIncreased = isPVFiboIncreased; + conditions.isPVFiboDecreased = isPVFiboDecreased; + conditions.isPVFiboSectionChanged = isPVFiboSectionChanged; + + // + // XPV Cycles ... + + // + double pvSCHH = conditions.pvSCHHs[curr]; + double pvSCLL = conditions.pvSCLLs[curr]; + double pvMCHH = conditions.pvMCHHs[curr]; + double pvMCLL = conditions.pvMCLLs[curr]; + double pvLCHH = conditions.pvLCHHs[curr]; + double pvLCLL = conditions.pvLCLLs[curr]; + double pvHCHH = conditions.pvHCHHs[curr]; + double pvHCLL = conditions.pvHCLLs[curr]; + + // + double pvSCHHPrev = conditions.pvSCHHs[prev]; + double pvSCLLPrev = conditions.pvSCLLs[prev]; + double pvMCHHPrev = conditions.pvMCHHs[prev]; + double pvMCLLPrev = conditions.pvMCLLs[prev]; + double pvLCHHPrev = conditions.pvLCHHs[prev]; + double pvLCLLPrev = conditions.pvLCLLs[prev]; + double pvHCHHPrev = conditions.pvHCHHs[prev]; + double pvHCLLPrev = conditions.pvHCLLs[prev]; + + // + double pvSCHHPrevPrev = conditions.pvSCHHs[prev + 1]; + double pvSCLLPrevPrev = conditions.pvSCLLs[prev + 1]; + double pvMCHHPrevPrev = conditions.pvMCHHs[prev + 1]; + double pvMCLLPrevPrev = conditions.pvMCLLs[prev + 1]; + double pvLCHHPrevPrev = conditions.pvLCHHs[prev + 1]; + double pvLCLLPrevPrev = conditions.pvLCLLs[prev + 1]; + double pvHCHHPrevPrev = conditions.pvHCHHs[prev + 1]; + double pvHCLLPrevPrev = conditions.pvHCLLs[prev + 1]; + + // + // Short ... + + // + bool isPVSCHHBullish = pvSCHH > pvSCHHPrev; + bool isPVSCHHBullishPrev = pvSCHHPrev > pvSCHHPrevPrev; + bool isPVSCLLBullish = pvSCLL > pvSCLLPrev; + bool isPVSCLLBullishPrev = pvSCLLPrev > pvSCLLPrevPrev; + bool isPVSCBullish = + // + isPVSCHHBullish && + isPVSCLLBullish + // + ; + bool isPVSCBullishPrev = + // + isPVSCHHBullishPrev && + isPVSCLLBullishPrev + // + ; + bool isPVSCSwitchedToBullish = + // + isPVSCBullish && + !isPVSCBullishPrev + // + ; + + // + bool isPVSCHHBearish = pvSCHH < pvSCHHPrev; + bool isPVSCHHBearishPrev = pvSCHHPrev < pvSCHHPrevPrev; + bool isPVSCLLBearish = pvSCLL < pvSCLLPrev; + bool isPVSCLLBearishPrev = pvSCLLPrev < pvSCLLPrevPrev; + bool isPVSCBearish = + // + isPVSCHHBearish && + isPVSCLLBearish + // + ; + bool isPVSCBearishPrev = + // + isPVSCHHBearishPrev && + isPVSCLLBearishPrev + // + ; + bool isPVSCSwitchedToBearish = + // + isPVSCBearish && + !isPVSCBearishPrev + // + ; + + // + // Medium ... + + // + bool isPVMCHHBullish = pvMCHH > pvMCHHPrev; + bool isPVMCHHBullishPrev = pvMCHHPrev > pvMCHHPrevPrev; + bool isPVMCLLBullish = pvMCLL > pvMCLLPrev; + bool isPVMCLLBullishPrev = pvMCLLPrev > pvMCLLPrevPrev; + bool isPVMCBullish = + // + isPVMCHHBullish && + isPVMCLLBullish + // + ; + bool isPVMCBullishPrev = + // + isPVMCHHBullishPrev && + isPVMCLLBullishPrev + // + ; + bool isPVMCSwitchedToBullish = + // + isPVMCBullish && + !isPVMCBullishPrev + // + ; + + // + bool isPVMCHHBearish = pvMCHH < pvMCHHPrev; + bool isPVMCHHBearishPrev = pvMCHHPrev < pvMCHHPrevPrev; + bool isPVMCLLBearish = pvMCLL < pvMCLLPrev; + bool isPVMCLLBearishPrev = pvMCLLPrev < pvMCLLPrevPrev; + bool isPVMCBearish = + // + isPVMCHHBearish && + isPVMCLLBearish + // + ; + bool isPVMCBearishPrev = + // + isPVMCHHBearishPrev && + isPVMCLLBearishPrev + // + ; + bool isPVMCSwitchedToBearish = + // + isPVMCBearish && + !isPVMCBearishPrev + // + ; + + // + // Long ... + + // + bool isPVLCHHBullish = pvLCHH > pvLCHHPrev; + bool isPVLCHHBullishPrev = pvLCHHPrev > pvLCHHPrevPrev; + bool isPVLCLLBullish = pvLCLL > pvLCLLPrev; + bool isPVLCLLBullishPrev = pvLCLLPrev > pvLCLLPrevPrev; + bool isPVLCBullish = + // + isPVLCHHBullish && + isPVLCLLBullish + // + ; + bool isPVLCBullishPrev = + // + isPVLCHHBullishPrev && + isPVLCLLBullishPrev + // + ; + bool isPVLCSwitchedToBullish = + // + isPVLCBullish && + !isPVLCBullishPrev + // + ; + + // + bool isPVLCHHBearish = pvLCHH < pvLCHHPrev; + bool isPVLCHHBearishPrev = pvLCHHPrev < pvLCHHPrevPrev; + bool isPVLCLLBearish = pvLCLL < pvLCLLPrev; + bool isPVLCLLBearishPrev = pvLCLLPrev < pvLCLLPrevPrev; + bool isPVLCBearish = + // + isPVLCHHBearish && + isPVLCLLBearish + // + ; + bool isPVLCBearishPrev = + // + isPVLCHHBearishPrev && + isPVLCLLBearishPrev + // + ; + bool isPVLCSwitchedToBearish = + // + isPVLCBearish && + !isPVLCBearishPrev + // + ; + + // + // Hind ... + + // + bool isPVHCHHBullish = pvHCHH > pvHCHHPrev; + bool isPVHCHHBullishPrev = pvHCHHPrev > pvHCHHPrevPrev; + bool isPVHCLLBullish = pvHCLL > pvHCLLPrev; + bool isPVHCLLBullishPrev = pvHCLLPrev > pvHCLLPrevPrev; + bool isPVHCBullish = + // + isPVHCHHBullish && + isPVHCLLBullish + // + ; + bool isPVHCBullishPrev = + // + isPVHCHHBullishPrev && + isPVHCLLBullishPrev + // + ; + bool isPVHCSwitchedToBullish = + // + isPVHCBullish && + !isPVHCBullishPrev + // + ; + + // + bool isPVHCHHBearish = pvHCHH < pvHCHHPrev; + bool isPVHCHHBearishPrev = pvHCHHPrev < pvHCHHPrevPrev; + bool isPVHCLLBearish = pvHCLL < pvHCLLPrev; + bool isPVHCLLBearishPrev = pvHCLLPrev < pvHCLLPrevPrev; + bool isPVHCBearish = + // + isPVHCHHBearish && + isPVHCLLBearish + // + ; + bool isPVHCBearishPrev = + // + isPVHCHHBearishPrev && + isPVHCLLBearishPrev + // + ; + bool isPVHCSwitchedToBearish = + // + isPVHCBearish && + !isPVHCBearishPrev + // + ; + + // + conditions.isPVSCHHBullish = isPVSCHHBullish; + conditions.isPVSCLLBullish = isPVSCLLBullish; + conditions.isPVSCBullish = isPVSCBullish; + conditions.isPVSCSwitchedToBullish = isPVSCSwitchedToBullish; + conditions.isPVSCHHBearish = isPVSCHHBearish; + conditions.isPVSCLLBearish = isPVSCLLBearish; + conditions.isPVSCBearish = isPVSCBearish; + conditions.isPVSCSwitchedToBearish = isPVSCSwitchedToBearish; + conditions.isPVMCHHBullish = isPVMCHHBullish; + conditions.isPVMCLLBullish = isPVMCLLBullish; + conditions.isPVMCBullish = isPVMCBullish; + conditions.isPVMCSwitchedToBullish = isPVMCSwitchedToBullish; + conditions.isPVMCHHBearish = isPVMCHHBearish; + conditions.isPVMCLLBearish = isPVMCLLBearish; + conditions.isPVMCBearish = isPVMCBearish; + conditions.isPVMCSwitchedToBearish = isPVMCSwitchedToBearish; + conditions.isPVLCHHBullish = isPVLCHHBullish; + conditions.isPVLCLLBullish = isPVLCLLBullish; + conditions.isPVLCBullish = isPVLCBullish; + conditions.isPVLCSwitchedToBullish = isPVLCSwitchedToBullish; + conditions.isPVLCHHBearish = isPVLCHHBearish; + conditions.isPVLCLLBearish = isPVLCLLBearish; + conditions.isPVLCBearish = isPVLCBearish; + conditions.isPVLCSwitchedToBearish = isPVLCSwitchedToBearish; + conditions.isPVHCHHBullish = isPVHCHHBullish; + conditions.isPVHCLLBullish = isPVHCLLBullish; + conditions.isPVHCBullish = isPVHCBullish; + conditions.isPVHCSwitchedToBullish = isPVHCSwitchedToBullish; + conditions.isPVHCHHBearish = isPVHCHHBearish; + conditions.isPVHCLLBearish = isPVHCLLBearish; + conditions.isPVHCBearish = isPVHCBearish; + conditions.isPVHCSwitchedToBearish = isPVHCSwitchedToBearish; + + // + // XSTR ... + + // + str.CopyTrend( + barIndex, + mNumberOfItems, + conditions.strTrends // + ); + str.CopyState( + barIndex, + mNumberOfItems, + conditions.strStates // + ); + + // + bool isTrendBullish = + // + str.IsBullish(str.GetState(curr)) + // + ; + bool isTrendBearish = + // + str.IsBearish(str.GetState(curr)) + // + ; + + // + bool isTrendBullishPrev = + // + str.IsBullish(str.GetState(prev)) + // + ; + bool isTrendBearishPrev = + // + str.IsBearish(str.GetState(prev)) + // + ; + + // + conditions.isTrendBullish = isTrendBullish; + conditions.isTrendBearish = isTrendBearish; + conditions.isTrendSwitchedToBullish = + // + isTrendBullish && + !isTrendBullishPrev + // + ; + conditions.isTrendSwitchedToBearish = + // + isTrendBearish && + !isTrendBearishPrev + // + ; + + // + // XCHE ... + + // + che.CopyLongExit1( + barIndex, + mNumberOfItems, + conditions.cheLongExit1s // + ); + che.CopyLongExit2( + barIndex, + mNumberOfItems, + conditions.cheLongExit2s // + ); + che.CopyShortExit1( + barIndex, + mNumberOfItems, + conditions.cheShortExit1s // + ); + che.CopyShortExit2( + barIndex, + mNumberOfItems, + conditions.cheShortExit2s // + ); + + // + bool isCHEInLong = + // + NotEmpty(che.GetLongExit1(curr)) + // + ; + bool isCHEInLongPrev = + // + NotEmpty(che.GetLongExit1(prev)) + // + ; + bool isCHEInStrongLong = + // + isCHEInLong && + NotEmpty(che.GetLongExit2(curr)) + // + ; + bool isCHEInStrongLongPrev = + // + isCHEInLongPrev && + NotEmpty(che.GetLongExit2(prev)) + // + ; + bool isCHEInShort = + // + NotEmpty(che.GetShortExit1(curr)) + // + ; + bool isCHEInShortPrev = + // + NotEmpty(che.GetShortExit1(prev)) + // + ; + bool isCHEInStrongShort = + // + isCHEInShort && + NotEmpty(che.GetShortExit2(curr)) + // + ; + bool isCHEInStrongShortPrev = + // + isCHEInShortPrev && + NotEmpty(che.GetShortExit2(prev)) + // + ; + + // + conditions.isCHEInLong = isCHEInLong; + conditions.isCHEInStrongLong = isCHEInStrongLong; + conditions.isCHESwitchedInStrongLong = + // + isCHEInStrongLong && + !isCHEInStrongLongPrev + // + ; + conditions.isCHEInShort = isCHEInShort; + conditions.isCHEInStrongShort = isCHEInStrongShort; + conditions.isCHESwitchedInStrongShort = + // + isCHEInStrongShort && + !isCHEInStrongShortPrev + // + ; + + // + // XMC ... + + // + mc.CopyFast( + barIndex, + mNumberOfItems, + conditions.mcFasts // + ); + mc.CopySlow( + barIndex, + mNumberOfItems, + conditions.mcSlows // + ); + mc.CopyVerifier( + barIndex, + mNumberOfItems, + conditions.mcVerifiers // + ); + + // + bool isFastOverSlow = + // + conditions.mcFasts[curr] > conditions.mcSlows[curr] && + conditions.mcFasts[prev] > conditions.mcSlows[prev] + // + ; + bool isFastUnderSlow = + // + conditions.mcFasts[curr] < conditions.mcSlows[curr] && + conditions.mcFasts[prev] < conditions.mcSlows[prev] + // + ; + bool isFastOverVerifier = + // + conditions.mcFasts[curr] > conditions.mcVerifiers[curr] && + conditions.mcFasts[prev] > conditions.mcVerifiers[prev] + // + ; + bool isFastUnderVerifier = + // + conditions.mcFasts[curr] < conditions.mcVerifiers[curr] && + conditions.mcFasts[prev] < conditions.mcVerifiers[prev] + // + ; + bool isSlowOverVerifier = + // + conditions.mcSlows[curr] > conditions.mcVerifiers[curr] && + conditions.mcSlows[prev] > conditions.mcVerifiers[prev] + // + ; + bool isSlowUnderVerifier = + // + conditions.mcSlows[curr] < conditions.mcVerifiers[curr] && + conditions.mcSlows[prev] < conditions.mcVerifiers[prev] + // + ; + bool isCloseOverFast = + // + pBar.close > conditions.mcFasts[prev] + // + ; + bool isCloseUnderFast = + // + pBar.close < conditions.mcFasts[prev] + // + ; + bool isCloseOverSlow = + // + pBar.close > conditions.mcSlows[prev] + // + ; + bool isCloseUnderSlow = + // + pBar.close < conditions.mcSlows[prev] + // + ; + bool isCloseOverVerifier = + // + pBar.close > conditions.mcVerifiers[prev] + // + ; + bool isCloseUnderVerifier = + // + pBar.close < conditions.mcVerifiers[prev] + // + ; + + // + bool isFastCrossedOverSlow = + // + conditions.mcFasts[curr] > conditions.mcSlows[curr] && + conditions.mcFasts[prev] <= conditions.mcSlows[prev] + // + ; + + // + bool isFastCrossedUnderSlow = + // + conditions.mcFasts[curr] < conditions.mcSlows[curr] && + conditions.mcFasts[prev] >= conditions.mcSlows[prev] + // + ; + + // + bool isFastCrossedOverVerifier = + // + conditions.mcFasts[curr] > conditions.mcVerifiers[curr] && + conditions.mcFasts[prev] <= conditions.mcVerifiers[prev] + // + ; + + // + bool isFastCrossedUnderVerifier = + // + conditions.mcFasts[curr] < conditions.mcVerifiers[curr] && + conditions.mcFasts[prev] >= conditions.mcVerifiers[prev] + // + ; + + // + bool isSlowCrossedOverVerifier = + // + conditions.mcSlows[curr] > conditions.mcVerifiers[curr] && + conditions.mcSlows[prev] <= conditions.mcVerifiers[prev] + // + ; + + // + bool isSlowCrossedUnderVerifier = + // + conditions.mcSlows[curr] < conditions.mcVerifiers[curr] && + conditions.mcSlows[prev] >= conditions.mcVerifiers[prev] + // + ; + + // + conditions.isFastOverSlow = isFastOverSlow; + conditions.isFastUnderSlow = isFastUnderSlow; + conditions.isFastOverVerifier = isFastOverVerifier; + conditions.isFastUnderVerifier = isFastUnderVerifier; + conditions.isSlowOverVerifier = isSlowOverVerifier; + conditions.isSlowUnderVerifier = isSlowUnderVerifier; + conditions.isCloseOverFast = isCloseOverFast; + conditions.isCloseUnderFast = isCloseUnderFast; + conditions.isCloseOverSlow = isCloseOverSlow; + conditions.isCloseUnderSlow = isCloseUnderSlow; + conditions.isCloseOverVerifier = isCloseOverVerifier; + conditions.isCloseUnderVerifier = isCloseUnderVerifier; + conditions.isFastCrossedOverSlow = isFastCrossedOverSlow; + conditions.isFastCrossedUnderSlow = isFastCrossedUnderSlow; + conditions.isFastCrossedOverVerifier = isFastCrossedOverVerifier; + conditions.isFastCrossedUnderVerifier = isFastCrossedUnderVerifier; + conditions.isSlowCrossedOverVerifier = isSlowCrossedOverVerifier; + conditions.isSlowCrossedUnderVerifier = isSlowCrossedUnderVerifier; + + // + // XICH ... + + // + ich.CopyTenkanSen( + barIndex, + mNumberOfItems, + conditions.ichTenkanSens // + ); + ich.CopyKijunSen( + barIndex, + mNumberOfItems, + conditions.ichKijunSens // + ); + ich.CopyChikouSpan( + barIndex, + mNumberOfItems, + conditions.ichChikouSpans // + ); + ich.CopySenkouSpanA( + barIndex, + mNumberOfItems, + conditions.ichSenkouSpanBs // + ); + ich.CopySenkouSpanB( + barIndex, + mNumberOfItems, + conditions.ichSenkouSpanAs // + ); + + // + double tenkanSen = ich.GetTenkanSen(curr); + double tenkanSenPrev = ich.GetTenkanSen(prev); + + // + double kijunSen = ich.GetKijunSen(curr); + double kijunSenPrev = ich.GetKijunSen(prev); + + // + double senkouSpanA = ich.GetSenkouSpanA(curr); + double senkouSpanAPrev = ich.GetSenkouSpanA(prev); + + // + double senkouSpanB = ich.GetSenkouSpanB(curr); + double senkouSpanBPrev = ich.GetSenkouSpanB(prev); + + // + double futureSenkouSpanA = ich.GetFutureSenkouSpanA(curr); + double futureSenkouSpanAPrev = ich.GetFutureSenkouSpanA(prev); + + // + double futureSenkouSpanB = ich.GetFutureSenkouSpanB(curr); + double futureSenkouSpanBPrev = ich.GetFutureSenkouSpanB(prev); + + // + bool isSenkouSpanAOverB = senkouSpanA > senkouSpanB; + bool isSenkouSpanAUnderB = senkouSpanA < senkouSpanB; + bool isSenkouSpanAOverLast = senkouSpanA > senkouSpanAPrev; + bool isSenkouSpanAUnderLast = senkouSpanA < senkouSpanAPrev; + bool isFutureSenkouSpanAOverB = futureSenkouSpanA > futureSenkouSpanB; + bool isFutureSenkouSpanAUnderB = futureSenkouSpanA < futureSenkouSpanB; + bool isFutureSenkouSpanAOverLast = futureSenkouSpanA > futureSenkouSpanAPrev; + bool isFutureSenkouSpanAUnderLast = futureSenkouSpanA < futureSenkouSpanAPrev; + bool isCloseOverKijunSen = pBar.close > kijunSenPrev; + bool isCloseUnderKijunSen = pBar.close < kijunSenPrev; + bool isTenkanSenOverKijunSen = tenkanSen > kijunSen; + bool isTenkanSenUnderKijunSen = tenkanSen < kijunSen; + bool isTenkanSenPrevOverKijunSen = tenkanSenPrev > kijunSenPrev; + bool isTenkanSenPrevUnderKijunSen = tenkanSenPrev < kijunSenPrev; + bool isTenkanSenCrossedOverKijunSen = + // + isTenkanSenOverKijunSen && + !isTenkanSenPrevOverKijunSen + // + ; + bool isTenkanSenCrossedUnderKijunSen = + // + isTenkanSenUnderKijunSen && + !isTenkanSenPrevUnderKijunSen + // + ; + + // + conditions.isSenkouSpanAOverB = isSenkouSpanAOverB; + conditions.isSenkouSpanAUnderB = isSenkouSpanAUnderB; + conditions.isSenkouSpanAOverLast = isSenkouSpanAOverLast; + conditions.isSenkouSpanAUnderLast = isSenkouSpanAUnderLast; + conditions.isFutureSenkouSpanAOverB = isFutureSenkouSpanAOverB; + conditions.isFutureSenkouSpanAUnderB = isFutureSenkouSpanAUnderB; + conditions.isFutureSenkouSpanAOverLast = isFutureSenkouSpanAOverLast; + conditions.isFutureSenkouSpanAUnderLast = isFutureSenkouSpanAUnderLast; + conditions.isCloseOverKijunSen = isCloseOverKijunSen; + conditions.isCloseUnderKijunSen = isCloseUnderKijunSen; + conditions.isTenkanSenOverKijunSen = isTenkanSenOverKijunSen; + conditions.isTenkanSenUnderKijunSen = isTenkanSenUnderKijunSen; + conditions.isTenkanSenCrossedOverKijunSen = isTenkanSenCrossedOverKijunSen; + conditions.isTenkanSenCrossedUnderKijunSen = isTenkanSenCrossedUnderKijunSen; + + // + // XOSC ... + + // + // ATR ... + osc.CopyATR( + barIndex, + mNumberOfItems, + conditions.oscAtrs // + ); + + // + // VOLUE ... + osc.CopyVolume( + barIndex, + mNumberOfItems, + conditions.oscVolumes // + ); + + // + // MOMENTUM ... + osc.CopyMomentum( + barIndex, + mNumberOfItems, + conditions.oscMomentums // + ); + + // + // SAR ... + osc.CopySAR( + barIndex, + mNumberOfItems, + conditions.oscSars // + ); + + // + // RVI ... + + // + osc.CopyRVI( + barIndex, + mNumberOfItems, + conditions.oscRviMains // + ); + osc.CopyRVISignal( + barIndex, + mNumberOfItems, + conditions.oscRviSignals // + ); + + // + double rvi = osc.GetRVI(curr); + double rviSignal = osc.GetRVISignal(curr); + + // + bool isRVILongStart = + // + rvi > 0 && + rviSignal > 0 && + rvi > rviSignal + // + ; + bool isRVILongStop = + // + rvi < 0 && + rviSignal < 0 && + rvi < rviSignal + // + ; + bool isRVIShortStart = + // + rvi < 0 && + rviSignal < 0 && + rvi < rviSignal + // + ; + bool isRVIShortStop = + // + rvi > 0 && + rviSignal > 0 && + rvi > rviSignal + // + ; + + // + conditions.isRVILongStart = isRVILongStart; + conditions.isRVILongStop = isRVILongStop; + conditions.isRVIShortStart = isRVIShortStart; + conditions.isRVIShortStop = isRVIShortStop; + + // + // RSI ... + + // + osc.CopyRSI( + barIndex, + mNumberOfItems, + conditions.oscRsis // + ); + + // + double rsi = osc.GetRSI(curr); + + // + bool isRSIUnder50 = + // + rsi < 50 + // + ; + bool isRSIOver70 = + // + rsi > 70 + // + ; + bool isRSIOver50 = + // + rsi > 50 + // + ; + bool isRSIUnder30 = + // + rsi < 30 + // + ; + + // + conditions.isRSIUnder50 = isRSIUnder50; + conditions.isRSIOver70 = isRSIOver70; + conditions.isRSIOver50 = isRSIOver50; + conditions.isRSIUnder30 = isRSIUnder30; + + // + // BULLPOWER ... + + // + osc.CopyBullPower( + barIndex, + mNumberOfItems, + conditions.oscBullPs // + ); + + // + double bullp = osc.GetBullPower(curr); + double bullpLast = osc.GetBullPower(prev); + + // + bool isBullPowerOverLast = + // + bullp > bullpLast + // + ; + bool isBullPoswerUnderLast = + // + bullp < bullpLast + // + ; + bool isBullPowerOverZero = + // + bullp > 0 + // + ; + bool isBullPoswerUnderZero = + // + bullp < 0 + // + ; + + // + conditions.isBullPowerOverLast = isBullPowerOverLast; + conditions.isBullPoswerUnderLast = isBullPoswerUnderLast; + conditions.isBullPowerOverZero = isBullPowerOverZero; + conditions.isBullPoswerUnderZero = isBullPoswerUnderZero; + + // + // BEARPOWER ... + + // + osc.CopyBearPower( + barIndex, + mNumberOfItems, + conditions.oscBearPs // + ); + + // + double bearp = osc.GetBearPower(curr); + double bearpLast = osc.GetBearPower(prev); + + // + bool isBearPowerOverLast = + // + bearp > bearpLast + // + ; + bool isBearPoswerUnderLast = + // + bearp < bearpLast + // + ; + bool isBearPowerOverZero = + // + bearp > 0 + // + ; + bool isBearPoswerUnderZero = + // + bearp < 0 + // + ; + + // + conditions.isBearPowerOverLast = isBearPowerOverLast; + conditions.isBearPoswerUnderLast = isBearPoswerUnderLast; + conditions.isBearPowerOverZero = isBearPowerOverZero; + conditions.isBearPoswerUnderZero = isBearPoswerUnderZero; + + // + // CCI ... + + // + osc.CopyCCI( + barIndex, + mNumberOfItems, + conditions.oscCcis // + ); + + // + double cci = osc.GetCCI(curr); + + // + bool isCCIPositive = + // + cci > 0 + // + ; + bool isCCINegative = + // + cci < 0 + // + ; + bool isCCIOverPositiveHundred = + // + cci > 100 + // + ; + bool isCCIUnderNegativeHundred = + // + cci < -100 + // + ; + + // + conditions.isCCIPositive = isCCIPositive; + conditions.isCCINegative = isCCINegative; + conditions.isCCIOverPositiveHundred = isCCIOverPositiveHundred; + conditions.isCCIUnderNegativeHundred = isCCIUnderNegativeHundred; + + // + // MACD ... + + // + osc.CopyMACD( + barIndex, + mNumberOfItems, + conditions.oscMacdMains // + ); + osc.CopyMACDSignal( + barIndex, + mNumberOfItems, + conditions.oscMacdSignals // + ); + + // + double macd = osc.GetMACD(curr); + double macdSignal = osc.GetMACDSignal(curr); + + // + bool isMACDPositiove = + // + macd > 0 + // + ; + bool isMACDNegative = + // + macd < 0 + // + ; + bool isMACDOverSignal = + // + macd > macdSignal + // + ; + bool isMACDUnderSignal = + // + macd < macdSignal + // + ; + + // + conditions.isMACDPositiove = isMACDPositiove; + conditions.isMACDNegative = isMACDNegative; + conditions.isMACDOverSignal = isMACDOverSignal; + conditions.isMACDUnderSignal = isMACDUnderSignal; + + // + // STOCH ... + + // + osc.CopySTOCH( + barIndex, + mNumberOfItems, + conditions.oscStochMains // + ); + osc.CopySTOCHSignal( + barIndex, + mNumberOfItems, + conditions.oscStochSignals // + ); + + // + double stoch = osc.GetSTOCH(curr); + double stochSignal = osc.GetSTOCHSignal(curr); + + // + bool isStochKOverD = + // + stoch > stochSignal + // + ; + bool isStochKDUnder50 = + // + stoch < 50 && + stochSignal < 50 + // + ; + bool isStochKUnderD = + // + stoch < stochSignal + // + ; + bool isStochKDOver50 = + // + stoch > 50 && + stochSignal > 50 + // + ; + bool isStochKDUnder20 = + // + stoch < 20 && + stochSignal < 20 + // + ; + bool isStochKDOver80 = + // + stoch > 80 && + stochSignal > 80 + // + ; + + // + conditions.isStochKOverD = isStochKOverD; + conditions.isStochKDUnder50 = isStochKDUnder50; + conditions.isStochKUnderD = isStochKUnderD; + conditions.isStochKDOver50 = isStochKDOver50; + conditions.isStochKDUnder20 = isStochKDUnder20; + conditions.isStochKDOver80 = isStochKDOver80; + + // + // STDDEV ... + + // + osc.CopySTDDEV( + barIndex, + mNumberOfItems, + conditions.oscStddevs // + ); + + // + double stdDevs[]; + osc.CopySTDDEV( + barIndex + 1, + 5, + stdDevs // + ); + double stdDevAVG = GetAverage(stdDevs); + + // + double stdDev = osc.GetSTDDEV(curr); + double stdDevLast = osc.GetSTDDEV(prev); + + // + bool isSTDDEVOverAVG = + // + stdDev > stdDevAVG + // + ; + bool isSTDDEVUnderAVG = + // + stdDev < stdDevAVG + // + ; + bool isSTDDEVOverLast = + // + stdDev > stdDevLast + // + ; + bool isSTDDEVUnderLast = + // + stdDev < stdDevLast + // + ; + + // + conditions.isSTDDEVOverAVG = isSTDDEVOverAVG; + conditions.isSTDDEVUnderAVG = isSTDDEVUnderAVG; + conditions.isSTDDEVOverLast = isSTDDEVOverLast; + conditions.isSTDDEVUnderLast = isSTDDEVUnderLast; + } + + // + // Market Parse Conditions ... + + // + // X786 Long ... + bool HasX786LongConditions() + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + XOHCL cBar = GetBar(cIndex); + XOHCL pBar = GetBar(pIndex); + + // + // XPV ... + + double cPVPeak = pv.GetPeak(cIndex); + double cPVVale = pv.GetVale(cIndex); + + // + double pPVPeak = pv.GetPeak(pIndex); + double pPVVale = pv.GetVale(pIndex); + + // + double cPVSup = pv.GetSupport(cIndex); + double pPVSup = pv.GetSupport(pIndex); + + // + double cPVRes = pv.GetResistance(cIndex); + double pPVRes = pv.GetResistance(pIndex); + + // + double cPVFib1 = pv.GetFib1(cIndex); + double cPVFib2 = pv.GetFib2(cIndex); + double cPVFib3 = pv.GetFib3(cIndex); + double cPVFib4 = pv.GetFib4(cIndex); + double cPVFib5 = pv.GetFib5(cIndex); + + // + double pPVFib1 = pv.GetFib1(pIndex); + double pPVFib2 = pv.GetFib2(pIndex); + double pPVFib3 = pv.GetFib3(pIndex); + double pPVFib4 = pv.GetFib4(pIndex); + double pPVFib5 = pv.GetFib5(pIndex); + + // + bool isNewPeak = cPVPeak != pPVPeak; + bool isNewPeakUnderLast = + // + isNewPeak && + cPVPeak < pPVPeak + // + ; + bool isNewPeakOverLast = + // + isNewPeak && + cPVPeak > pPVPeak + // + ; + + // + bool isNewVale = cPVVale != pPVVale; + bool isNewValeUnderLast = + // + isNewVale && + cPVVale < pPVVale + // + ; + bool isNewValeOverLast = + // + isNewVale && + cPVVale > pPVVale + // + ; + + // + bool isFiboIncreased = + // + cPVFib1 > pPVFib1 && + cPVFib2 > pPVFib2 && + cPVFib3 > pPVFib3 && + cPVFib4 > pPVFib4 && + cPVFib5 > pPVFib5 + // + ; + + // + bool isFiboDecreased = + // + cPVFib1 < pPVFib1 && + cPVFib2 < pPVFib2 && + cPVFib3 < pPVFib3 && + cPVFib4 < pPVFib4 && + cPVFib5 < pPVFib5 + // + ; + + // + bool isFiboSectionChanged = + // + (isFiboDecreased && + isNewPeakUnderLast) + // + || + // + (isFiboIncreased && + isNewValeOverLast) + // + ; + + // + // XHK ... + + // + XOHCL cSMHKBar; + hk.SMAsOHCL( + cSMHKBar, + cIndex // + ); + + // + XOHCL pSMHKBar; + hk.SMAsOHCL( + pSMHKBar, + pIndex // + ); + + // + bool isCSMHKBullish = cSMHKBar.IsBullish(); + bool isCSMHKBearish = cSMHKBar.IsBearish(); + + // + bool isPSMHKBullish = pSMHKBar.IsBullish(); + bool isPSMHKBearish = pSMHKBar.IsBearish(); + + // + bool isSMHKBullish = isCSMHKBullish; + bool isSMHKBearish = isCSMHKBearish; + bool isSMHKSwitchedToBullish = + // + isCSMHKBullish && + isPSMHKBearish + // + ; + + // + bool isSMHKSwitchedToBearish = + // + isCSMHKBearish && + isPSMHKBullish + // + ; + + // + // XSTR ... + + // + ENUM_XSTR_TREND_STATES cStrState = str + .GetState(cIndex); + double cStrTrend = str.GetTrend(cIndex); + bool isCStrBullish = cStrState == X_STR_BULLISH; + bool isCStrBearish = cStrState == X_STR_BEARISH; + + // + ENUM_XSTR_TREND_STATES pStrState = str + .GetState(pIndex); + double pStrTrend = str.GetTrend(pIndex); + bool isPStrBullish = pStrState == X_STR_BULLISH; + bool isPStrBearish = pStrState == X_STR_BEARISH; + + // + bool isTrendBullish = isCStrBullish; + bool isTrendBearish = isCStrBearish; + + // + bool isTrendSwitchedToBullish = + // + isCStrBullish && + !isPStrBullish + // + ; + + // + bool isTrendSwitchedToBearish = + // + isCStrBearish && + !isPStrBearish + // + ; + + // + // XTD ... + + // + double cTDBullish = td.GetBullish(cIndex); + double pTDBullish = td.GetBullish(pIndex); + + // + double cTDBearish = td.GetBearish(cIndex); + double pTDBearish = td.GetBearish(pIndex); + + // + bool isCTDBullish = + // + cTDBullish > cTDBearish + // + ; + + // + bool isCTDBearish = + // + cTDBearish > cTDBullish + // + ; + + // + bool isPTDBullish = + // + pTDBullish > pTDBearish + // + ; + + // + bool isPTDBearish = + // + pTDBearish > pTDBullish + // + ; + + // + bool isTDBullish = isCTDBullish; + bool isTDBearish = isCTDBearish; + bool isTDSwitchedToBullish = + // + isCTDBullish && + !isPTDBullish + // + ; + bool isTDSwitchedToBearish = + // + isCTDBearish && + !isPTDBearish + // + ; + + // + // XCHE ... + + // + double cCHELongExit1 = che.GetLongExit1(cIndex); + double cCHELongExit2 = che.GetLongExit2(cIndex); + + // + double pCHELongExit1 = che.GetLongExit1(pIndex); + double pCHELongExit2 = che.GetLongExit2(pIndex); + + // + double cCHEShortExit1 = che.GetShortExit1(cIndex); + double cCHEShortExit2 = che.GetShortExit2(cIndex); + + // + double pCHEShortExit1 = che.GetShortExit1(pIndex); + double pCHEShortExit2 = che.GetShortExit2(pIndex); + + // + bool CCHEHasLongExit1 = NotEmpty(cCHELongExit1); + bool CCHEHasLongExit2 = NotEmpty(cCHELongExit2); + + // + bool CCHEHasShortExit1 = NotEmpty(cCHEShortExit1); + bool CCHEHasShortExit2 = NotEmpty(cCHEShortExit2); + + // + bool PCHEHasLongExit1 = NotEmpty(pCHELongExit1); + bool PCHEHasLongExit2 = NotEmpty(pCHELongExit2); + + // + bool PCHEHasShortExit1 = NotEmpty(pCHEShortExit1); + bool PCHEHasShortExit2 = NotEmpty(pCHEShortExit2); + + // + bool isCCHEBullish = + // + CCHEHasLongExit1 && + CCHEHasLongExit2 + // + ; + + // + bool isCCHEBearish = + // + CCHEHasShortExit1 && + CCHEHasShortExit2 + // + ; + + // + bool isPCHEBullish = + // + PCHEHasLongExit1 && + PCHEHasLongExit2 + // + ; + + // + bool isPCHEBearish = + // + PCHEHasShortExit1 && + PCHEHasShortExit2 + // + ; + + // + bool isCHEBullish = isCCHEBullish; + bool isCHEBearish = isCCHEBearish; + bool isCHESwitchedToBullish = + // + isCCHEBullish && + !isPCHEBullish + // + ; + bool isCHESwitchedToBearish = + // + isCCHEBearish && + !isPCHEBearish + // + ; + + // + double cDONUpperOpen = don.GetUpperO(cIndex); + double cDONUpperClose = don.GetUpperC(cIndex); + double cDONUpperHigh = don.GetUpperH(cIndex); + double cDONUpperLow = don.GetUpperL(cIndex); + + // + double cDONLowerOpen = don.GetLowerO(cIndex); + double cDONLowerClose = don.GetLowerC(cIndex); + double cDONLowerHigh = don.GetLowerH(cIndex); + double cDONLowerLow = don.GetLowerL(cIndex); + + // + double pDONUpperOpen = don.GetUpperO(pIndex); + double pDONUpperClose = don.GetUpperC(pIndex); + double pDONUpperHigh = don.GetUpperH(pIndex); + double pDONUpperLow = don.GetUpperL(pIndex); + + // + double pDONLowerOpen = don.GetLowerO(pIndex); + double pDONLowerClose = don.GetLowerC(pIndex); + double pDONLowerHigh = don.GetLowerH(pIndex); + double pDONLowerLow = don.GetLowerL(pIndex); + + // + bool isBarCrossedDownDONLowerHigh = + // + cBar.IsBreakDown(pDONLowerHigh) + // + ; + + // + bool isBarCrossedUpDONLowerHigh = + // + cBar.IsBreakUp(pDONLowerHigh) + // + ; + + // + result = + // + (isSMHKSwitchedToBullish && + (isTDBullish && + isCHEBullish && + isTrendBullish)) + // + || + // + (isTDSwitchedToBullish && + (isSMHKBullish && + isCHEBullish && + isTrendBullish)) + // + || + // + (isCHESwitchedToBullish && + (isTDBullish && + isSMHKBullish && + isTrendBullish)) + // + || + // + (isTrendSwitchedToBullish && + (isTDBullish && + isCHEBullish && + isSMHKBullish)) + // + ; + + // + return result; + } + + // + // X786 Short ... + bool HasX786ShortConditions() + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + XOHCL cBar = GetBar(cIndex); + XOHCL pBar = GetBar(pIndex); + + // + // XPV ... + + double cPVPeak = pv.GetPeak(cIndex); + double cPVVale = pv.GetVale(cIndex); + + // + double pPVPeak = pv.GetPeak(pIndex); + double pPVVale = pv.GetVale(pIndex); + + // + double cPVSup = pv.GetSupport(cIndex); + double pPVSup = pv.GetSupport(pIndex); + + // + double cPVRes = pv.GetResistance(cIndex); + double pPVRes = pv.GetResistance(pIndex); + + // + double cPVFib1 = pv.GetFib1(cIndex); + double cPVFib2 = pv.GetFib2(cIndex); + double cPVFib3 = pv.GetFib3(cIndex); + double cPVFib4 = pv.GetFib4(cIndex); + double cPVFib5 = pv.GetFib5(cIndex); + + // + double pPVFib1 = pv.GetFib1(pIndex); + double pPVFib2 = pv.GetFib2(pIndex); + double pPVFib3 = pv.GetFib3(pIndex); + double pPVFib4 = pv.GetFib4(pIndex); + double pPVFib5 = pv.GetFib5(pIndex); + + // + bool isNewPeak = cPVPeak != pPVPeak; + bool isNewPeakUnderLast = + // + isNewPeak && + cPVPeak < pPVPeak + // + ; + bool isNewPeakOverLast = + // + isNewPeak && + cPVPeak > pPVPeak + // + ; + + // + bool isNewVale = cPVVale != pPVVale; + bool isNewValeUnderLast = + // + isNewVale && + cPVVale < pPVVale + // + ; + bool isNewValeOverLast = + // + isNewVale && + cPVVale > pPVVale + // + ; + + // + bool isFiboIncreased = + // + cPVFib1 > pPVFib1 && + cPVFib2 > pPVFib2 && + cPVFib3 > pPVFib3 && + cPVFib4 > pPVFib4 && + cPVFib5 > pPVFib5 + // + ; + + // + bool isFiboDecreased = + // + cPVFib1 < pPVFib1 && + cPVFib2 < pPVFib2 && + cPVFib3 < pPVFib3 && + cPVFib4 < pPVFib4 && + cPVFib5 < pPVFib5 + // + ; + + // + bool isFiboSectionChanged = + // + (isFiboDecreased && + isNewPeakUnderLast) + // + || + // + (isFiboIncreased && + isNewValeOverLast) + // + ; + + // + // XHK ... + + // + XOHCL cSMHKBar; + hk.SMAsOHCL( + cSMHKBar, + cIndex // + ); + + // + XOHCL pSMHKBar; + hk.SMAsOHCL( + pSMHKBar, + pIndex // + ); + + // + bool isCSMHKBullish = cSMHKBar.IsBullish(); + bool isCSMHKBearish = cSMHKBar.IsBearish(); + + // + bool isPSMHKBullish = pSMHKBar.IsBullish(); + bool isPSMHKBearish = pSMHKBar.IsBearish(); + + // + bool isSMHKBullish = isCSMHKBullish; + bool isSMHKBearish = isCSMHKBearish; + bool isSMHKSwitchedToBullish = + // + isCSMHKBullish && + isPSMHKBearish + // + ; + + // + bool isSMHKSwitchedToBearish = + // + isCSMHKBearish && + isPSMHKBullish + // + ; + + // + // XSTR ... + + // + ENUM_XSTR_TREND_STATES cStrState = str + .GetState(cIndex); + double cStrTrend = str.GetTrend(cIndex); + bool isCStrBullish = cStrState == X_STR_BULLISH; + bool isCStrBearish = cStrState == X_STR_BEARISH; + + // + ENUM_XSTR_TREND_STATES pStrState = str + .GetState(pIndex); + double pStrTrend = str.GetTrend(pIndex); + bool isPStrBullish = pStrState == X_STR_BULLISH; + bool isPStrBearish = pStrState == X_STR_BEARISH; + + // + bool isTrendBullish = isCStrBullish; + bool isTrendBearish = isCStrBearish; + + // + bool isTrendSwitchedToBullish = + // + isCStrBullish && + !isPStrBullish + // + ; + + // + bool isTrendSwitchedToBearish = + // + isCStrBearish && + !isPStrBearish + // + ; + + // + // XTD ... + + // + double cTDBullish = td.GetBullish(cIndex); + double pTDBullish = td.GetBullish(pIndex); + + // + double cTDBearish = td.GetBearish(cIndex); + double pTDBearish = td.GetBearish(pIndex); + + // + bool isCTDBullish = + // + cTDBullish > cTDBearish + // + ; + + // + bool isCTDBearish = + // + cTDBearish > cTDBullish + // + ; + + // + bool isPTDBullish = + // + pTDBullish > pTDBearish + // + ; + + // + bool isPTDBearish = + // + pTDBearish > pTDBullish + // + ; + + // + bool isTDBullish = isCTDBullish; + bool isTDBearish = isCTDBearish; + bool isTDSwitchedToBullish = + // + isCTDBullish && + !isPTDBullish + // + ; + bool isTDSwitchedToBearish = + // + isCTDBearish && + !isPTDBearish + // + ; + + // + // XCHE ... + + // + double cCHELongExit1 = che.GetLongExit1(cIndex); + double cCHELongExit2 = che.GetLongExit2(cIndex); + + // + double pCHELongExit1 = che.GetLongExit1(pIndex); + double pCHELongExit2 = che.GetLongExit2(pIndex); + + // + double cCHEShortExit1 = che.GetShortExit1(cIndex); + double cCHEShortExit2 = che.GetShortExit2(cIndex); + + // + double pCHEShortExit1 = che.GetShortExit1(pIndex); + double pCHEShortExit2 = che.GetShortExit2(pIndex); + + // + bool CCHEHasLongExit1 = NotEmpty(cCHELongExit1); + bool CCHEHasLongExit2 = NotEmpty(cCHELongExit2); + + // + bool CCHEHasShortExit1 = NotEmpty(cCHEShortExit1); + bool CCHEHasShortExit2 = NotEmpty(cCHEShortExit2); + + // + bool PCHEHasLongExit1 = NotEmpty(pCHELongExit1); + bool PCHEHasLongExit2 = NotEmpty(pCHELongExit2); + + // + bool PCHEHasShortExit1 = NotEmpty(pCHEShortExit1); + bool PCHEHasShortExit2 = NotEmpty(pCHEShortExit2); + + // + bool isCCHEBullish = + // + CCHEHasLongExit1 && + CCHEHasLongExit2 + // + ; + + // + bool isCCHEBearish = + // + CCHEHasShortExit1 && + CCHEHasShortExit2 + // + ; + + // + bool isPCHEBullish = + // + PCHEHasLongExit1 && + PCHEHasLongExit2 + // + ; + + // + bool isPCHEBearish = + // + PCHEHasShortExit1 && + PCHEHasShortExit2 + // + ; + + // + bool isCHEBullish = isCCHEBullish; + bool isCHEBearish = isCCHEBearish; + bool isCHESwitchedToBullish = + // + isCCHEBullish && + !isPCHEBullish + // + ; + bool isCHESwitchedToBearish = + // + isCCHEBearish && + !isPCHEBearish + // + ; + + // + double cDONUpperOpen = don.GetUpperO(cIndex); + double cDONUpperClose = don.GetUpperC(cIndex); + double cDONUpperHigh = don.GetUpperH(cIndex); + double cDONUpperLow = don.GetUpperL(cIndex); + + // + double cDONLowerOpen = don.GetLowerO(cIndex); + double cDONLowerClose = don.GetLowerC(cIndex); + double cDONLowerHigh = don.GetLowerH(cIndex); + double cDONLowerLow = don.GetLowerL(cIndex); + + // + double pDONUpperOpen = don.GetUpperO(pIndex); + double pDONUpperClose = don.GetUpperC(pIndex); + double pDONUpperHigh = don.GetUpperH(pIndex); + double pDONUpperLow = don.GetUpperL(pIndex); + + // + double pDONLowerOpen = don.GetLowerO(pIndex); + double pDONLowerClose = don.GetLowerC(pIndex); + double pDONLowerHigh = don.GetLowerH(pIndex); + double pDONLowerLow = don.GetLowerL(pIndex); + + // + bool isBarCrossedDownDONLowerHigh = + // + cBar.IsBreakDown(pDONLowerHigh) + // + ; + + // + bool isBarCrossedUpDONLowerHigh = + // + cBar.IsBreakUp(pDONLowerHigh) + // + ; + + // + result = + // + (isSMHKSwitchedToBearish && + (isTDBearish && + isCHEBearish && + isTrendBearish)) + // + || + // + (isTDSwitchedToBearish && + (isSMHKBearish && + isCHEBearish && + isTrendBearish)) + // + || + // + (isCHESwitchedToBearish && + (isTDBearish && + isSMHKBearish && + isTrendBearish)) + // + || + // + (isTrendSwitchedToBearish && + (isTDBearish && + isCHEBearish && + isSMHKBearish)) + // + ; + + // + return result; + } + + // + // X121 Long ... + bool HasX121LongConditions() + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + XOHCL cBar = GetBar(cIndex); + XOHCL pBar = GetBar(pIndex); + + // + // XSTR ... + + // + ENUM_XSTR_TREND_STATES cStrState = str + .GetState(cIndex); + double cStrTrend = str.GetTrend(cIndex); + bool isCStrBullish = cStrState == X_STR_BULLISH; + bool isCStrBearish = cStrState == X_STR_BEARISH; + + // + ENUM_XSTR_TREND_STATES pStrState = str + .GetState(pIndex); + double pStrTrend = str.GetTrend(pIndex); + bool isPStrBullish = pStrState == X_STR_BULLISH; + bool isPStrBearish = pStrState == X_STR_BEARISH; + + // + bool isTrendBullish = isCStrBullish; + bool isTrendBearish = isCStrBearish; + + // + bool isTrendSwitchedToBullish = + // + isCStrBullish && + !isPStrBullish + // + ; + + // + bool isTrendSwitchedToBearish = + // + isCStrBearish && + !isPStrBearish + // + ; + + // + // XCHE ... + + // + double cCHELongExit1 = che.GetLongExit1(cIndex); + double cCHELongExit2 = che.GetLongExit2(cIndex); + + // + double pCHELongExit1 = che.GetLongExit1(pIndex); + double pCHELongExit2 = che.GetLongExit2(pIndex); + + // + double cCHEShortExit1 = che.GetShortExit1(cIndex); + double cCHEShortExit2 = che.GetShortExit2(cIndex); + + // + double pCHEShortExit1 = che.GetShortExit1(pIndex); + double pCHEShortExit2 = che.GetShortExit2(pIndex); + + // + bool CCHEHasLongExit1 = NotEmpty(cCHELongExit1); + bool CCHEHasLongExit2 = NotEmpty(cCHELongExit2); + + // + bool CCHEHasShortExit1 = NotEmpty(cCHEShortExit1); + bool CCHEHasShortExit2 = NotEmpty(cCHEShortExit2); + + // + bool PCHEHasLongExit1 = NotEmpty(pCHELongExit1); + bool PCHEHasLongExit2 = NotEmpty(pCHELongExit2); + + // + bool PCHEHasShortExit1 = NotEmpty(pCHEShortExit1); + bool PCHEHasShortExit2 = NotEmpty(pCHEShortExit2); + + // + bool isCCHEBullish = + // + CCHEHasLongExit1 && + CCHEHasLongExit2 + // + ; + + // + bool isCCHEBearish = + // + CCHEHasShortExit1 && + CCHEHasShortExit2 + // + ; + + // + bool isPCHEBullish = + // + PCHEHasLongExit1 && + PCHEHasLongExit2 + // + ; + + // + bool isPCHEBearish = + // + PCHEHasShortExit1 && + PCHEHasShortExit2 + // + ; + + // + bool isCHEBullish = isCCHEBullish; + bool isCHEBearish = isCCHEBearish; + bool isCHESwitchedToBullish = + // + isCCHEBullish && + !isPCHEBullish + // + ; + bool isCHESwitchedToBearish = + // + isCCHEBearish && + !isPCHEBearish + // + ; + + // + // XMC ... + + // + double cMCFast = mc.GetFast(cIndex); + double pMCFast = mc.GetFast(pIndex); + + // + double cMCSlow = mc.GetSlow(cIndex); + double pMCSlow = mc.GetSlow(pIndex); + + // + double cMCVerifier = mc.GetVerifier(cIndex); + double pMCVerifier = mc.GetVerifier(pIndex); + + // + bool isCMCFastOverSlow = cMCFast > cMCSlow; + bool isPMCFastOverSlow = pMCFast > pMCSlow; + + // + bool isCMCFastUnderSlow = cMCFast < cMCSlow; + bool isPMCFastUnderSlow = pMCFast < pMCSlow; + + // + bool isCMCFastOverVerifier = cMCFast > cMCVerifier; + bool isPMCFastOverVerifier = pMCFast > pMCVerifier; + + // + bool isCMCFastUnderVerifier = cMCFast < cMCVerifier; + bool isPMCFastUnderVerifier = pMCFast < pMCVerifier; + + // + bool isCMCSlowOverVerifier = cMCSlow > cMCVerifier; + bool isPMCSlowOverVerifier = pMCSlow > pMCVerifier; + + // + bool isCMCSlowUnderVerifier = cMCSlow < cMCVerifier; + bool isPMCSlowUnderVerifier = pMCSlow < pMCVerifier; + + // + bool isMCFastOverSlow = isCMCFastOverSlow; + bool isMCFastUnderSlow = isCMCFastUnderSlow; + bool isMCFastOverVerifier = isCMCFastOverVerifier; + bool isMCFastUnderVerifier = isCMCFastUnderVerifier; + bool isMCSlowOverVerifier = isCMCSlowOverVerifier; + bool isMCSlowUnderVerifier = isCMCSlowUnderVerifier; + + // + bool isMCFastCrossedOverSlow = + // + isCMCFastOverSlow && + !isPMCFastOverSlow + // + ; + bool isMCFastCrossedUnderSlow = + // + isCMCFastUnderSlow && + !isPMCFastUnderSlow + // + ; + + // + bool isMCFastCrossedOverVerifier = + // + isCMCFastOverVerifier && + !isPMCFastOverVerifier + // + ; + bool isMCFastCrossedUnderVerifier = + // + isCMCFastUnderVerifier && + !isPMCFastUnderVerifier + // + ; + + // + bool isMCSlowCrossedOverVerifier = + // + isCMCSlowOverVerifier && + !isPMCSlowOverVerifier + // + ; + bool isMCSlowCrossedUnderVerifier = + // + isCMCSlowUnderVerifier && + !isPMCSlowUnderVerifier + // + ; + + // + // XMRB ... + + // + double cMRBFast = mrb.GetFast(cIndex); + double pMRBFast = mrb.GetFast(pIndex); + + // + double cMRBSlow = mrb.GetSlow(cIndex); + double pMRBSlow = mrb.GetSlow(pIndex); + + // + bool isCMRBFastOverSlow = cMRBFast > cMRBSlow; + bool isPMRBFastOverSlow = pMRBFast > pMRBSlow; + + // + bool isCMRBFastUnderSlow = cMRBFast < cMRBSlow; + bool isPMRBFastUnderSlow = pMRBFast < pMRBSlow; + + // + bool isMRBFastOverSlow = isCMRBFastOverSlow; + bool isMRBFastUnderSlow = isCMRBFastUnderSlow; + + // + bool isMRBFastCrossedOverSlow = + // + isCMRBFastOverSlow && + !isPMRBFastOverSlow + // + ; + bool isMRBFastCrossedUnderSlow = + // + isCMRBFastUnderSlow && + !isPMRBFastUnderSlow + // + ; + + // + // Combine MRB and MC ... + + // + bool isCMRBFastOverVerifier = cMRBFast > cMCVerifier; + bool isPMRBFastOverVerifier = pMRBFast > pMCVerifier; + + // + bool isCMRBFastUnderVerifier = cMRBFast < cMCVerifier; + bool isPMRBFastUnderVerifier = pMRBFast < pMCVerifier; + + // + bool isCMRBSlowOverVerifier = cMRBSlow > cMCVerifier; + bool isPMRBSlowOverVerifier = pMRBSlow > pMCVerifier; + + // + bool isCMRBSlowUnderVerifier = cMRBSlow < cMCVerifier; + bool isPMRBSlowUnderVerifier = pMRBSlow < pMCVerifier; + + // + bool isMRBFastOverVerifier = isCMRBFastOverVerifier; + bool isMRBFastUnderVerifier = isCMRBFastUnderVerifier; + + // + bool isMRBFastCrossedtOverVerifier = + // + isCMRBFastOverVerifier && + !isPMRBFastOverVerifier + // + ; + + // + bool isMRBFastCrossedUnderVerifier = + // + isCMRBFastUnderVerifier && + !isPMRBFastUnderVerifier + // + ; + + // + bool isMRBSlowOverVerifier = isCMRBSlowOverVerifier; + bool isMRBSlowUnderVerifier = isCMRBSlowUnderVerifier; + + // + bool isMRBSlowCrossedtOverVerifier = + // + isCMRBSlowOverVerifier && + !isPMRBSlowOverVerifier + // + ; + + // + bool isMRBSlowCrossedUnderVerifier = + // + isCMRBSlowUnderVerifier && + !isPMRBSlowUnderVerifier + // + ; + + // + result = + // + (isMRBFastCrossedOverSlow && + (isCHEBullish && + isTrendBullish && + isMCFastOverSlow)) + // + || + // + (isMRBSlowCrossedtOverVerifier && + (isCHEBullish && + isTrendBullish && + isMCFastOverSlow && + isMRBFastOverSlow)) + // + || + // + (isCHESwitchedToBullish && + (isTrendBullish && + isMCFastOverSlow && + isMRBFastOverSlow)) + // + ; + + // + return result; + } + + // + // X121 Short ... + bool HasX121ShortConditions() + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + XOHCL cBar = GetBar(cIndex); + XOHCL pBar = GetBar(pIndex); + + // + // XSTR ... + + // + ENUM_XSTR_TREND_STATES cStrState = str + .GetState(cIndex); + double cStrTrend = str.GetTrend(cIndex); + bool isCStrBullish = cStrState == X_STR_BULLISH; + bool isCStrBearish = cStrState == X_STR_BEARISH; + + // + ENUM_XSTR_TREND_STATES pStrState = str + .GetState(pIndex); + double pStrTrend = str.GetTrend(pIndex); + bool isPStrBullish = pStrState == X_STR_BULLISH; + bool isPStrBearish = pStrState == X_STR_BEARISH; + + // + bool isTrendBullish = isCStrBullish; + bool isTrendBearish = isCStrBearish; + + // + bool isTrendSwitchedToBullish = + // + isCStrBullish && + !isPStrBullish + // + ; + + // + bool isTrendSwitchedToBearish = + // + isCStrBearish && + !isPStrBearish + // + ; + + // + // XCHE ... + + // + double cCHELongExit1 = che.GetLongExit1(cIndex); + double cCHELongExit2 = che.GetLongExit2(cIndex); + + // + double pCHELongExit1 = che.GetLongExit1(pIndex); + double pCHELongExit2 = che.GetLongExit2(pIndex); + + // + double cCHEShortExit1 = che.GetShortExit1(cIndex); + double cCHEShortExit2 = che.GetShortExit2(cIndex); + + // + double pCHEShortExit1 = che.GetShortExit1(pIndex); + double pCHEShortExit2 = che.GetShortExit2(pIndex); + + // + bool CCHEHasLongExit1 = NotEmpty(cCHELongExit1); + bool CCHEHasLongExit2 = NotEmpty(cCHELongExit2); + + // + bool CCHEHasShortExit1 = NotEmpty(cCHEShortExit1); + bool CCHEHasShortExit2 = NotEmpty(cCHEShortExit2); + + // + bool PCHEHasLongExit1 = NotEmpty(pCHELongExit1); + bool PCHEHasLongExit2 = NotEmpty(pCHELongExit2); + + // + bool PCHEHasShortExit1 = NotEmpty(pCHEShortExit1); + bool PCHEHasShortExit2 = NotEmpty(pCHEShortExit2); + + // + bool isCCHEBullish = + // + CCHEHasLongExit1 && + CCHEHasLongExit2 + // + ; + + // + bool isCCHEBearish = + // + CCHEHasShortExit1 && + CCHEHasShortExit2 + // + ; + + // + bool isPCHEBullish = + // + PCHEHasLongExit1 && + PCHEHasLongExit2 + // + ; + + // + bool isPCHEBearish = + // + PCHEHasShortExit1 && + PCHEHasShortExit2 + // + ; + + // + bool isCHEBullish = isCCHEBullish; + bool isCHEBearish = isCCHEBearish; + bool isCHESwitchedToBullish = + // + isCCHEBullish && + !isPCHEBullish + // + ; + bool isCHESwitchedToBearish = + // + isCCHEBearish && + !isPCHEBearish + // + ; + + // + // XMC ... + + // + double cMCFast = mc.GetFast(cIndex); + double pMCFast = mc.GetFast(pIndex); + + // + double cMCSlow = mc.GetSlow(cIndex); + double pMCSlow = mc.GetSlow(pIndex); + + // + double cMCVerifier = mc.GetVerifier(cIndex); + double pMCVerifier = mc.GetVerifier(pIndex); + + // + bool isCMCFastOverSlow = cMCFast > cMCSlow; + bool isPMCFastOverSlow = pMCFast > pMCSlow; + + // + bool isCMCFastUnderSlow = cMCFast < cMCSlow; + bool isPMCFastUnderSlow = pMCFast < pMCSlow; + + // + bool isCMCFastOverVerifier = cMCFast > cMCVerifier; + bool isPMCFastOverVerifier = pMCFast > pMCVerifier; + + // + bool isCMCFastUnderVerifier = cMCFast < cMCVerifier; + bool isPMCFastUnderVerifier = pMCFast < pMCVerifier; + + // + bool isCMCSlowOverVerifier = cMCSlow > cMCVerifier; + bool isPMCSlowOverVerifier = pMCSlow > pMCVerifier; + + // + bool isCMCSlowUnderVerifier = cMCSlow < cMCVerifier; + bool isPMCSlowUnderVerifier = pMCSlow < pMCVerifier; + + // + bool isMCFastOverSlow = isCMCFastOverSlow; + bool isMCFastUnderSlow = isCMCFastUnderSlow; + bool isMCFastOverVerifier = isCMCFastOverVerifier; + bool isMCFastUnderVerifier = isCMCFastUnderVerifier; + bool isMCSlowOverVerifier = isCMCSlowOverVerifier; + bool isMCSlowUnderVerifier = isCMCSlowUnderVerifier; + + // + bool isMCFastCrossedOverSlow = + // + isCMCFastOverSlow && + !isPMCFastOverSlow + // + ; + bool isMCFastCrossedUnderSlow = + // + isCMCFastUnderSlow && + !isPMCFastUnderSlow + // + ; + + // + bool isMCFastCrossedOverVerifier = + // + isCMCFastOverVerifier && + !isPMCFastOverVerifier + // + ; + bool isMCFastCrossedUnderVerifier = + // + isCMCFastUnderVerifier && + !isPMCFastUnderVerifier + // + ; + + // + bool isMCSlowCrossedOverVerifier = + // + isCMCSlowOverVerifier && + !isPMCSlowOverVerifier + // + ; + bool isMCSlowCrossedUnderVerifier = + // + isCMCSlowUnderVerifier && + !isPMCSlowUnderVerifier + // + ; + + // + // XMRB ... + + // + double cMRBFast = mrb.GetFast(cIndex); + double pMRBFast = mrb.GetFast(pIndex); + + // + double cMRBSlow = mrb.GetSlow(cIndex); + double pMRBSlow = mrb.GetSlow(pIndex); + + // + bool isCMRBFastOverSlow = cMRBFast > cMRBSlow; + bool isPMRBFastOverSlow = pMRBFast > pMRBSlow; + + // + bool isCMRBFastUnderSlow = cMRBFast < cMRBSlow; + bool isPMRBFastUnderSlow = pMRBFast < pMRBSlow; + + // + bool isMRBFastOverSlow = isCMRBFastOverSlow; + bool isMRBFastUnderSlow = isCMRBFastUnderSlow; + + // + bool isMRBFastCrossedOverSlow = + // + isCMRBFastOverSlow && + !isPMRBFastOverSlow + // + ; + bool isMRBFastCrossedUnderSlow = + // + isCMRBFastUnderSlow && + !isPMRBFastUnderSlow + // + ; + + // + result = + // + (isMRBFastCrossedUnderSlow && + (isCHEBearish && + isTrendBearish && + isMCFastUnderSlow && + isMCFastUnderVerifier)) + // + ; + + // + return result; + } + + // + + // + // Initial Market Cycle ... + bool Init( + X121MCycleInputs &inputs // Inputs for Initialization + ) + { + // + bool result = false; + + // + // Validate Input ... + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + string symbol = mInputs.cycle.symbol; + ENUM_TIMEFRAMES period = mInputs.cycle.period; + + // + // Init Helpers ... + + // + // XHK ... + result = hk.Init( + symbol, + period, + mInputs.hkInputs + // + ); + if (!result) + { + return result; + } + + // + // XMC ... + result = mc.Init( + symbol, + period, + mInputs.mcInputs + // + ); + if (!result) + { + return result; + } + + // + // XPV ... + result = pv.Init( + symbol, + period, + mInputs.pvInputs + // + ); + if (!result) + { + return result; + } + + // + // XZG ... + result = zg.Init( + symbol, + period, + mInputs.zgInputs + // + ); + if (!result) + { + return result; + } + + // + // XTD ... + result = td.Init( + symbol, + period, + mInputs.tdInputs + // + ); + if (!result) + { + return result; + } + + // + // XMRB ... + result = mrb.Init( + symbol, + period, + mInputs.mrbInputs + // + ); + if (!result) + { + return result; + } + + // + // XSTR ... + result = str.Init( + symbol, + period, + mInputs.strInputs + // + ); + if (!result) + { + return result; + } + + // + // XCHE ... + result = che.Init( + symbol, + period, + mInputs.cheInputs + // + ); + if (!result) + { + return result; + } + + // + // XOSC ... + result = osc.Init( + symbol, + period, + mInputs.oscInputs + // + ); + if (!result) + { + return result; + } + + // + // XICH ... + result = ich.Init( + symbol, + period, + mInputs.ichInputs + // + ); + if (!result) + { + return result; + } + + // + // XDON ... + result = don.Init( + symbol, + period, + mInputs.donInputs + // + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Draw Tools ... + // + // Completely Draw Bars ... + void Draw( + long chartID, // Chart ID ... + int subWindow, // Chart Sub Window ... + int &offset // Distance used for Labels ... + ) + { + // + if (mInputs.drawCBar || mInputs.drawPBar) + { + // + DrawOHCL( + chartID, + subWindow, + mInputs.drawLabels, + !mInputs.drawCBar && mInputs.drawPBar, + !mInputs.drawPBar && mInputs.drawCBar, + offset + // + ); + + // + if (mInputs.drawLabels) + { + offset += 3; + } + } + + // + if (mInputs.drawCBarMid || mInputs.drawPBarMid) + { + // + DrawMidLine( + chartID, + subWindow, + mInputs.drawLabels, + !mInputs.drawCBarMid && mInputs.drawPBarMid, + !mInputs.drawPBarMid && mInputs.drawCBarMid, + offset + // + ); + + // + if (mInputs.drawLabels) + { + // + if (mInputs.drawCBarMid) + { + offset++; + } + + // + if (mInputs.drawPBarMid) + { + offset++; + } + } + } + } + + // + // Draw Functions ... + // + // Draw Middle Line of Cycle ... + void DrawOHCL( + long chartID, + int subWindow, + bool drawLabel = false, // Specify Draw Label of Mid Line or not ... + bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ... + bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ... + int offset = 0 // Distance used for Labels ... + ) + { + // + if (offset < 0) + { + offset = 0; + } + + // + string baseTag = ToString(mInputs.cycle.cycle); + + // + XOHCL cBar = GetBar(0); + XOHCL pBar = GetBar(1); + + // + datetime fromCDate = GetBarTime(0); + datetime fromPDate = GetBarTime(1); + + // + datetime cTime = TimeCurrent(); + + // + // Try to Draw ... + + // + bool canDrawPrev = !drawOnlyCurrent; + bool canDrawCurrent = !drawOnlyPrev; + + // + // Set Cycles Color based on Current Candle ... + + // + bool isCBarBullish = + cBar.IsBullish(); + + // + bool isPBarBullish = + pBar.IsBearish(); + + // + color clrTemoBullishColor = mInputs.cBarDrawSpecs.openStyle.clr; + color clrTemoBearishColor = mInputs.cBarDrawSpecs.closeStyle.clr; + + // + color cBarSelectedColor = isCBarBullish ? clrTemoBullishColor : clrTemoBearishColor; + color pBarSelectedColor = isPBarBullish ? clrTemoBullishColor : clrTemoBearishColor; + + // + mInputs.cBarDrawSpecs.openStyle.clr = cBarSelectedColor; + mInputs.cBarDrawSpecs.openStyle.labelColor = cBarSelectedColor; + + // + mInputs.cBarDrawSpecs.closeStyle.clr = cBarSelectedColor; + mInputs.cBarDrawSpecs.closeStyle.labelColor = cBarSelectedColor; + + // + mInputs.pBarDrawSpecs.openStyle.clr = pBarSelectedColor; + mInputs.pBarDrawSpecs.openStyle.labelColor = pBarSelectedColor; + + // + mInputs.pBarDrawSpecs.closeStyle.clr = pBarSelectedColor; + mInputs.pBarDrawSpecs.closeStyle.labelColor = pBarSelectedColor; + + // + if (canDrawPrev) + { + offset++; + } + + // + // Label ... + if (drawLabel) + { + // + if (canDrawPrev) + { + // + // Draw Prev Bar Lables ... + + // + DrawXOHCLLabel( + chartID, + subWindow, + pBar, + mInputs.pBarDrawSpecs, + "P", + cTime, + offset - 1 + // + ); + + // + offset += 3; + } + + // + if (canDrawCurrent) + { + // + // Draw Current Bar Lables ... + + // + DrawXOHCLLabel( + chartID, + subWindow, + cBar, + mInputs.cBarDrawSpecs, + "C", + cTime, + offset + // + ); + } + } + + // + // Line ... + + // + if (canDrawPrev) + { + // + // Draw Cycle Prev Bar ... + DrawXOHCLContent( + chartID, + subWindow, + pBar, + mInputs.pBarDrawSpecs, + "P", + fromPDate + // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Cycle Current Bar ... + DrawXOHCLContent( + chartID, + subWindow, + cBar, + mInputs.cBarDrawSpecs, + "C", + fromCDate + // + ); + } + } + + // + // Draw Middle Line of Cycle ... + void DrawMidLine( + long chartID, + int subWindow, + bool drawLabel = false, // Specify Draw Label of Mid Line or not ... + bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ... + bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ... + int offset = 0 // Distance used for Labels ... + ) + { + // + if (offset < 0) + { + offset = 0; + } + + // + // Calculate Mid Line ... + XOHCL cBar = GetBar(0); + double cMidLine = cBar.GetMid(); + + // + XOHCL pBar = GetBar(1); + double pMidLine = pBar.GetMid(); + + // + string baseTag = ToString(mInputs.cycle.cycle); + + // + string midCTag = baseTag + "|MID|C|"; + string midPTag = baseTag + "|MID|P|"; + + // + string midCLblTag = midCTag + "lbl"; + string midPLblTag = midPTag + "lbl"; + + // + datetime fromCDate = GetBarTime(0); + datetime fromPDate = GetBarTime(1); + + // + datetime cTime = TimeCurrent(); + + // + // Try to Draw ... + + // + bool canDrawPrev = !drawOnlyCurrent; + bool canDrawCurrent = !drawOnlyPrev; + + // + if (canDrawPrev) + { + offset++; + } + + // + // Label ... + if (drawLabel) + { + // + if (canDrawPrev) + { + // + // Draw Prev Candle MidLine Lable ... + DrawLabel( + chartID, + subWindow, + mInputs.pBarMidDrawSpecs, + midPLblTag, + cTime, + pMidLine, + offset // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Current Candle MidLine Label ... + DrawLabel( + chartID, + subWindow, + mInputs.cBarMidDrawSpecs, + midCLblTag, + cTime, + cMidLine, + offset - 1 // + ); + } + } + + // + // Line ... + + // + if (canDrawPrev) + { + // + // Draw Prev Candle MidLine ... + DrawLine( + chartID, + subWindow, + mInputs.pBarMidDrawSpecs, + midPTag, + fromPDate, + pMidLine // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Current Candle MidLine ... + DrawLine( + chartID, + subWindow, + mInputs.cBarMidDrawSpecs, + midCTag, + fromCDate, + cMidLine // + ); + } + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + + // + X121MCycleInputs mInputs; + + // + // Tools ... + + // + bool Update(int hostBarIndex = 0) + { + return mInputs.cycle.Update(hostBarIndex); + } + + // + // Draw Functions ... + + // + // Draw OHCL Labels ... + void DrawXOHCLLabel( + long chartID, + int subWindow, + XOHCL &bar, // Specify Cycle XOHCL Model to Draw ... + XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ... + string baseTag, // Specify a Unique Tag ... + datetime time, // Draw Time ... + int offset = 0 // + ) + { + // + // Open ... + string openTag = mInputs.cycle.prefix + "_" + baseTag + "_O_lbl"; + DrawLabel( + chartID, + subWindow, + specs.openStyle, + openTag, + time, + bar.open, + offset + // + ); + + // + // High ... + string highTag = mInputs.cycle.prefix + "_" + baseTag + "_H_lbl"; + DrawLabel( + chartID, + subWindow, + specs.highStyle, + highTag, + time, + bar.high, + offset + 1 + // + ); + + // + // Close ... + string closeTag = mInputs.cycle.prefix + "_" + baseTag + "_C_lbl"; + DrawLabel( + chartID, + subWindow, + specs.closeStyle, + closeTag, + time, + bar.close, + offset + 2 + // + ); + + // + // Low ... + string lowTag = mInputs.cycle.prefix + "_" + baseTag + "_L_lbl"; + DrawLabel( + chartID, + subWindow, + specs.lowStyle, + lowTag, + time, + bar.low, + offset + 3 + // + ); + } + + // + // Draw XOHCL Content ... + void DrawXOHCLContent( + long chartID, + int subWindow, + XOHCL &bar, // Specify Cycle XOHCL Model to Draw ... + XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ... + string baseTag, // Specify a Unique Tag ... + datetime time // Draw Time ... + ) + { + // + // Open ... + string openTag = mInputs.cycle.prefix + "_" + baseTag + "_O"; + DrawLine( + chartID, + subWindow, + specs.openStyle, + openTag, + time, + bar.open + // + ); + + // + // High ... + string highTag = mInputs.cycle.prefix + "_" + baseTag + "_H"; + DrawLine( + chartID, + subWindow, + specs.highStyle, + highTag, + time, + bar.high + // + ); + + // + // Close ... + string closeTag = mInputs.cycle.prefix + "_" + baseTag + "_C"; + DrawLine( + chartID, + subWindow, + specs.closeStyle, + closeTag, + time, + bar.close + // + ); + + // + // Low ... + string lowTag = mInputs.cycle.prefix + "_" + baseTag + "_L"; + DrawLine( + chartID, + subWindow, + specs.lowStyle, + lowTag, + time, + bar.low + // + ); + } + + // + // Draw Label Using Specifications ... + void DrawLabel( + long chartID, + int subWindow, + XDrawSpecifications &specs, + string tag, + datetime time, + double price, + int offset = 0 // + ) + { + // + if (offset < 0) + { + offset = 0; + } + + // + int offsetSeconds = PeriodSeconds(mInputs.cycle.hostPeriod) * offset; + + // + string value = specs.label; + + // + DrawText( + chartID, + tag, + subWindow, + time - offsetSeconds, + price, + specs.label, + specs.labelFont, + specs.labelFontSize, + specs.labelColor, + specs.labelAngel, + specs.labelAnchor, + specs.back, + specs.selection, + specs.hidden, + specs.zOrder // + ); + } + + // + // Draw TrendLine Using Specifications ... + void DrawLine( + long chartID, + int subWindow, + XDrawSpecifications &specs, + string tag, + datetime fromDate, + double fromPrice, + datetime toDate = NULL, + double toPrice = 0 // + ) + { + // + if (toPrice <= 0) + { + toPrice = fromPrice; + } + + // + if (toDate == 0 || toDate == NULL) + { + toDate = TimeCurrent(); + } + + // + DrawTrendLine( + chartID, + tag, + subWindow, + fromDate, + fromPrice, + toDate, + toPrice, + specs.clr, + specs.style, + specs.width, + specs.back, + specs.selection, + specs.rayRight, + specs.hidden, + specs.zOrder // + ); + } +}; + +// +// Tools ... + +// +struct X121MarketCycleDescriptor +{ + // + string symbol; // Trading Symbol + ENUM_TIMEFRAMES hostPeriod; // Host Period + ENUM_X_MARKET_CYCLES cycle; // Init Cycle + ENUM_TIMEFRAMES period; // Cycle Period + ENUM_X_PERIOD_METHOD periodMethod; // Cycle Period Method + string prefix; // Prefix + bool useDefaults; // Use Inputs Default Settings ... + + // + X121MCycleInputs inputs; // Inputs + + // + XSCX121Market *market; // Market + + // + X121MCycleConditions conditions; // Market Conditions + + // + // Tools ... + + // + bool Init() + { + // + bool result = false; + + // + result = inputs.Init( + symbol, + hostPeriod, + cycle, + period, + periodMethod, + prefix, + useDefaults // + ); + if (!result) + { + return result; + } + + // + + // + // Instantiate Market ... + market = new XSCX121Market(); + + // + // Initialize Market ... + result = market.Init(inputs); + + // + return result; + } + + // + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + ENUM_TIMEFRAMES mPeriod, // Cycle Period + ENUM_X_PERIOD_METHOD mPeriodMethod, // Cycle Period Method + string mPrefix = "", // Prefix + bool mUseDefaults = true // Use Inputs Default Settings ... + ) + { + // + bool result = false; + + // + result = + // + IsValid(mSymbol) && + IsValid(mHostPeriod) && + IsValid(mPeriodMethod, mPeriod) + // + ; + if (!result) + { + return result; + } + + // + this.cycle = mCycle; + this.symbol = mSymbol; + this.period = mPeriod; + this.prefix = mPrefix; + this.hostPeriod = mHostPeriod; + this.useDefaults = mUseDefaults; + this.periodMethod = mPeriodMethod; + + // + result = this.Init(); + + // + return result; + } +}; + +// +// Custom Draws ... + +// +// Custom Struct Draws ... +bool DrawSupRes( + XOHCLSupRes &item, // Struct item to Draw ... + XDrawSpecifications &supSpecs, // Supports specs ... + XDrawSpecifications &resSpecs, // Resistances specs ... + long chartID = 0, + int subWindow = 0, + string prefix = "SupRes" // +) +{ + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + datetime cTime = TimeCurrent(); + datetime pTime = TimeCurrent() - PeriodSeconds(PERIOD_M10); + + // + // Support ... + int supCount = item.CountSupports(); + bool canDrawSups = IsValidSize(supCount) && supSpecs.draw; + if (canDrawSups) + { + // + for (int i = 0; i < supCount; i++) + { + // + double iSup = item.sup[i]; + + // + string supName = prefix + "_" + "Sup_" + ToString(iSup); + + // + DrawTrendLine( + chartID, + supName, + subWindow, + pTime, + iSup, + cTime, + iSup, + supSpecs.clr, + supSpecs.style, + supSpecs.width, + supSpecs.back, + supSpecs.selection, + supSpecs.rayRight, + supSpecs.hidden, + supSpecs.zOrder // + ); + + // + if (IsValid(supSpecs.label)) + { + // + DrawText( + chartID, + supName + "_lbl", + subWindow, + cTime, + iSup, + supSpecs.label, + supSpecs.labelFont, + supSpecs.labelFontSize, + supSpecs.labelColor, + supSpecs.labelAngel, + supSpecs.labelAnchor, + supSpecs.back, + supSpecs.selection, + supSpecs.hidden, + supSpecs.zOrder // + ); + } + } + } + + // + // Resistance ... + int resCount = item.CountResistances(); + bool canDrawRess = IsValidSize(supCount) && supSpecs.draw; + if (canDrawRess) + { + // + for (int i = 0; i < resCount; i++) + { + // + double iRes = item.res[i]; + + // + string resName = prefix + "_" + "Res_" + ToString(iRes); + + // + DrawTrendLine( + chartID, + resName, + subWindow, + pTime, + iRes, + cTime, + iRes, + resSpecs.clr, + resSpecs.style, + resSpecs.width, + resSpecs.back, + resSpecs.selection, + resSpecs.rayRight, + resSpecs.hidden, + resSpecs.zOrder // + ); + + // + if (IsValid(resSpecs.label)) + { + // + DrawText( + chartID, + resName + "_lbl", + subWindow, + cTime, + iRes, + resSpecs.label, + resSpecs.labelFont, + resSpecs.labelFontSize, + resSpecs.labelColor, + resSpecs.labelAngel, + resSpecs.labelAnchor, + resSpecs.back, + resSpecs.selection, + resSpecs.hidden, + resSpecs.zOrder // + ); + } + } + } + + // + result = canDrawSups || canDrawRess; + + // + return result; +} + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xaccount.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xaccount.class.mq5 new file mode 100644 index 0000000..66169f5 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xaccount.class.mq5 @@ -0,0 +1,398 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCAccount +// Description: provides all Account requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Classes/x-saherelm.base.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Manage Account ... +class XSCAccount : public XSCBase +{ + // + // Public ... +public: + // + // Constructor ... + void XSCAccount() + { + // + mAccountInfo = new CAccountInfo(); + } + + // + // Deconstructor ... + void ~XSCAccount() + { + } + + // + // START Provided Functions ... + // + + // + // User Account ... + long GetUserAccount() + { + return mAccountInfo.Login(); + } + + // + // Account Leverage ... + long GetLeverage() + { + return mAccountInfo.Leverage(); + } + + // + // Get Trade Expert State ... + bool CanExpertTrade() + { + return mAccountInfo.TradeExpert(); + } + + // + // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... + // -------------------------- + // ACCOUNT_TRADE_MODE_DEMO + // ACCOUNT_TRADE_MODE_CONTEST + // ACCOUNT_TRADE_MODE_REAL + ENUM_ACCOUNT_TRADE_MODE GetTradeMode() + { + return mAccountInfo.TradeMode(); + } + + // + // Get Account Balance ... + double GetBalance() + { + return mAccountInfo.Balance(); + } + + // + // Get the amount of give Credit ... + double GetCredit() + { + return mAccountInfo.Credit(); + } + + // + // Get the amount of current Profit on account ... + double GetProfit() + { + return mAccountInfo.Profit(); + } + + // + // Get the amount of current Equity on account ... + double GetEquity() + { + return mAccountInfo.Equity(); + } + + // + // Get the amount of reserved Margin ... + double GetMargin() + { + return mAccountInfo.Margin(); + } + + // + // Get the amount of free Margin ... + double GetFreeMargin() + { + return mAccountInfo.FreeMargin(); + } + + // + // Get the Level of Margin ... + double GetMarginLevel() + { + return mAccountInfo.MarginLevel(); + } + + // + // Get the Level Of Margin for a Deposit ... + double GetMarginCall() + { + return mAccountInfo.MarginCall(); + } + + // + // Get the Level of Margin for Stop out ... + double GetMarginStopOut() + { + return mAccountInfo.MarginStopOut(); + } + + // + // Get the Client Name ... + string GetName() + { + return mAccountInfo.Name(); + } + + // + // Get the Trade Server Name ... + string GetServerName() + { + return mAccountInfo.Server(); + } + + // + // Get deposit Currency Name ... + string GetCurrency() + { + return mAccountInfo.Currency(); + } + + // + // Get the Company Name that serves an Account ... + string GetCompany() + { + return mAccountInfo.Company(); + } + + // + // Calculate Profits for the current account based on passed parameters ... + double CalculateTradeProfit( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry, // open price + double exit // close price + ) + { + // + double result = mAccountInfo.OrderProfitCheck( + symbol, + type, + volume, + entry, + exit); + + // + return result; + } + + // + // Calculate amount of margin which required for trade operation ... + double CalculateMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.MarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate amount of free margin left after trade operation ... + double CalculateFreeMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.FreeMarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate the Maximum possible volume of trade operation ... + double CalculateMaxVolume( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double entry, // open price + double percent = 100 // percent of available margin + ) + { + // + double result = mAccountInfo.MaxLotCheck( + symbol, + type, + entry, + percent); + + // + return result; + } + + // + // Calculate Point Value for Given Symbol based on Account ... + double GetPointValue( + string symbol // trading symbol + ) + { + // + double result = 0; + + // + double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); + double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); + double point = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + double ticksPerPoint = tickSize / point; + + // + result = tickValue / ticksPerPoint; + + // + return result; + } + + // + // Calculate Risk Amount based on account Currency by Providing: + // Points and Volume ... + double CalculateRiskAmount( + string symbol, // trading symbol + double points, // amount of Risk Points + double volume // position Volume + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = pointValue * volume * points; + + // + return result; + } + + // + // Calculate Risk Points based on account Currency by Providing: + // Volume and Amount ... + double CalculateRiskPoints( + string symbol, // trading symbol + double volume, // position Volume + double amount // amount of Risk based on Account Currency + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * volume); + + // + return result; + } + + // + // Calculate Volume based on account Currency by Providing: + // Amount and Risk Points ... + double CalculateVolume( + string symbol, // trading symbol + double amount, // amount of Risk based on Account Currency + double points // amount of Risk Points + ) + { + // + double result = 0; + + // + points = + points <= 0 + ? 10 + : points; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * points); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xalert.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xalert.class.mq5 new file mode 100644 index 0000000..de28ce2 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xalert.class.mq5 @@ -0,0 +1,1363 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCAlert +// Description: provides all Alerts requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +// Class Definition ... + +class XSCAlert : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + XSCAlert() {} + XSCAlert( + string prefix = "X-Alert", // Alerts Prefixe + bool enableAlerts = true, // Enable Alerts + bool logAlerts = true, // Log Alerts + bool terminalAlerts = false, // Terminal Alerts + bool mailAlerts = false, // Mail Alerts + bool pushAlerts = false // Push Alerts + ) + { + // + mPrefix = prefix; + mLogAlerts = logAlerts; + mMailAlerts = mailAlerts; + mPushAlerts = pushAlerts; + mEnableAlerts = enableAlerts; + mTerminalAlerts = terminalAlerts; + + // + // Normalize Prefix if Not Provided ... + if (!IsValid(mPrefix)) + { + mPrefix = GetTag(); + } + } + + // + // Deconstructor ... + ~XSCAlert() {} + + // + // Override ... + string GetTag() override + { + return GetSpecificToken(this); + } + + // + // Properties Getter(s) / Setter(s) ... + + // + string GetPrefix() + { + return mPrefix; + } + + // + void SetPrefix(string value) + { + mPrefix = value; + } + + // + bool GetLogAlerts() + { + return mLogAlerts; + } + + // + void SetLogAlerts(bool value) + { + mLogAlerts = value; + } + + // + bool GetEnableAlerts() + { + return mEnableAlerts; + } + + // + void SetEnableAlerts(bool value) + { + mEnableAlerts = value; + } + + // + bool GetPushAlerts() + { + return mPushAlerts; + } + + // + void SetPushAlerts(bool value) + { + mPushAlerts = value; + } + + // + bool GetMailAlerts() + { + return mMailAlerts; + } + + // + void SetMailAlerts(bool value) + { + mMailAlerts = value; + } + + // + bool GetTerminalAlerts() + { + return mTerminalAlerts; + } + + // + void SetTerminalAlerts(bool value) + { + mTerminalAlerts = value; + } + + // + // Tools Funtions ... + + // + // Alerts ... + + // + // Logging an Alert ... + void LogAlert(string message) + { + // + // Validate Args ... + if (!CanLogAlert()) + { + return; + } + + // + Log(message); + } + + // + // Terminal Alert ... + void TerminalAlert(string message) + { + // + // Validate Args ... + if (!CanTerminalAlert()) + { + return; + } + + // + // Prepare Message ... + message = PrepareMessage(message); + + // Send Terminal Alert ... + Alert(message); + } + + // + // Mail Alert ... + void MailAlert(string message) + { + // + // Validate Args ... + if (!CanMailAlert()) + { + return; + } + + // + // Send Mail Alert ... + SendMail(GetPrefix(), message); + } + + // + // Send Push Notification ... + void PushAlert(string message) + { + // + // Validate Args ... + if (!CanPushAlert()) + { + return; + } + + // + // Prepare Message ... + message = PrepareMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); + } + + // + // Send an Alert by Handling all Different Specified + // type's of Alert's if they are Enabled ... + void Alert(string message) + { + // + // Handle Log, if Enabled ... + LogAlert(message); + + // + // Handle Mail if Enabled ... + MailAlert(message); + + // + // Handle Push if Enabled ... + PushAlert(message); + + // + // Handle Terminal if Enabled ... + TerminalAlert(message); + } + + // + // Logs ... + + // + // Log a Message ... + void Log(string message) + { + // + if (!CanLog()) + { + return; + } + + // + Print(GetPrefix(), " > ", message); + } + void Log(string tag, string message) + { + // + if (!CanLog()) + { + return; + } + + // + Print(GetPrefix(), "_", tag, " > ", message); + } + void LogEmpty() + { + // + if (!CanLog()) + { + return; + } + + // + Print(" "); + } + + // + // Log Specific Array ... + template + void LogArray( + T &array[], // Array to Log + string label = NULL // Array Label + ) + { + // + if (!CanLog()) + { + return; + } + + // + Print(GetPrefix(), ">", (IsValid(label) ? label : "")); + ArrayPrint(array); + } + + // + // Error ... + + // + // Log an Error ... + void LogError( + int error = -1 // Specific Error, if it's equal to -1, use Last Error ... + ) + { + // + if (!CanLog()) + { + return; + } + + // + if (error <= -1) + { + error = GetLastError(); + } + + // + string errorMsg = GetErrorDescription(error); + + // + Log("Error: " + errorMsg); + } + + // + // Retrieve Specified Error Code Description ... + string GetErrorDescription(int err_code) + { + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; + } + + // + // Retrieve Specified Error Code Description ... + string GetTradeServerReturnCodeDescription(int return_code) + { + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... + + // + bool CanLog() + { + return mLogAlerts; + } + + // + bool CanLogAlert() + { + // + bool result = GetEnableAlerts() && GetLogAlerts(); + + // + return result; + } + + // + bool CanTerminalAlert() + { + // + bool result = GetEnableAlerts() && GetTerminalAlerts(); + + // + return result; + } + + // + bool CanMailAlert() + { + // + bool result = GetEnableAlerts() && GetMailAlerts(); + + // + return result; + } + + // + bool CanPushAlert() + { + // + bool result = GetEnableAlerts() && GetPushAlerts(); + + // + return result; + } + +private: + // + // Props ... + string mPrefix; // Alerts Prefixe + bool mEnableAlerts; // Enable Alerts + bool mLogAlerts; // Log Alerts + bool mTerminalAlerts; // Terminal Alerts + bool mMailAlerts; // Mail Alerts + bool mPushAlerts; // Push Alerts + + // + // Tools ... + + // + // Clear Escape String and + // Attach Alert Prefix to Message ... + string PrepareMessage(string message) + { + // + StringReplace(message, "\n", " | "); + + // + StringConcatenate(message, GetPrefix(), " > ", message); + + // + return message; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xdata-collector.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xdata-collector.class.mq5 new file mode 100644 index 0000000..8160865 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xdata-collector.class.mq5 @@ -0,0 +1,481 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCDataCollector +// Description: provides Data Collection Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +template +class XSCDataCollector : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + void XSCDataCollector( + string path = NULL, // Base Folder for Data Store + string fileName = NULL // File Name for Data Store + ) + { + // + if (!IsValid(path)) + { + path = GetType(); + } + + // + if (!IsValid(fileName)) + { + fileName = GetType() + ".txt"; + } + + // + Path(path); + FileName(fileName); + } + + // + // Deconstructor ... + void ~XSCDataCollector() {} + + // + // Properties ... + + // + bool Path(string value) + { + // + bool result = false; + + // + result = IsValid(value); + if (!result) + { + return result; + } + + // + result = value != mPath; + if (!result) + { + return result; + } + + // + mPath = value; + + // + return result; + } + + // + string Path() + { + return mPath; + } + + // + bool FileName(string value) + { + // + bool result = false; + + // + result = IsValid(value); + if (!result) + { + return result; + } + + // + result = value != mFileName; + if (!result) + { + return result; + } + + // + mFileName = value; + + // + return result; + } + + // + string FileName() + { + return mFileName; + } + + // + // Tools ... + + // + // Clear Exists Collected Data ... + void Clear() + { + // + ResetLastError(); + + // + string dataStorePath = GetStorePath(); + + // + // Check Data Store Exists or not ... + bool isExists = FileIsExist(dataStorePath); + if (!isExists) + { + return; + } + + // + FileDelete(dataStorePath); + } + + // + // Collect All Stored Items ... + int Collect( + T &items[] // Hold Result + ) + { + // + int result = 0; + + // + Clean(items); + + // + // Reading Store Whole Content ... + + // + string storePath = GetStorePath(); + int mFileHandler = FileOpen( + storePath, + FILE_READ | FILE_TXT); + result = mFileHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Parse Store Content and Read Data ... + while (!FileIsEnding(mFileHandler)) + { + // + // Each Line Represent One Model ... + string content = FileReadString(mFileHandler); + + // + T iItem; + bool isValid = iItem.ParseModel(content); + if (isValid) + { + // + AddRef( + iItem, + items + // + ); + } + } + + // + // Close File ... + FileClose(mFileHandler); + + // + result = ArraySize(items); + + // + return result; + } + + // + // Add Item ... + bool Add( + T &item // Item to Store + ) + { + // + bool result = false; + + // + result = item.IsModelValid(); + if (!result) + { + return result; + } + + // + string content = item.ToModelString(); + result = IsValid(content); + if (!result) + { + return result; + } + + // + string storePath = GetStorePath(); + int mFileHandler = FileOpen( + storePath, + FILE_READ | FILE_WRITE | FILE_TXT); + result = mFileHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileSeek(mFileHandler, 0, SEEK_END); + FileWrite(mFileHandler, content); + FileFlush(mFileHandler); + FileClose(mFileHandler); + + // + return result; + } + + // + // Add Item ... + bool Add( + string content // Content + ) + { + // + bool result = false; + + // + result = IsValid(content); + if (!result) + { + return result; + } + + // + string storePath = GetStorePath(); + int mFileHandler = FileOpen( + storePath, + FILE_READ | FILE_WRITE | FILE_TXT); + result = mFileHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileSeek(mFileHandler, 0, SEEK_END); + FileWrite(mFileHandler, content); + FileFlush(mFileHandler); + FileClose(mFileHandler); + + // + return result; + } + + // + // Add Items ... + int Add( + T &items[] // Items to Add ... + ) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + T iItem = items[i]; + + // + if (!iItem.IsModelValid()) + { + continue; + } + + // + bool isAdded = Add(iItem); + if (isAdded) + { + result++; + } + } + + // + return result; + } + + // + // Remove Item ... + bool Remove( + T &item // Item to Remove + ) + { + // + bool result = false; + + // + result = item.IsModelValid(); + if (!result) + { + return result; + } + + // + T items[]; + int itemsCount = Collect(items); + if (itemsCount <= 0) + { + return result; + } + + // + int itemIndex = item.FindIndex(items); + result = ArrayRemove( + items, + itemIndex, + 1); + if (!result) + { + return result; + } + + // + Clear(); + + // + int itemsAdded = Add(items); + + // + result = itemsAdded == ArraySize(items); + + // + return result; + } + + // + // Protected ... +protected: + // + // Tools ... + + // + // Retrieve Type of Class as String ... + string GetType() + { + // + string mType = (string) typename(T); + + // + string result = mType; + + // + string parts[]; + int partsCount = SplitContent( + parts, + result, + " " + // + ); + if (partsCount <= 0) + { + // + result = mType; + return result; + } + + // + bool hasLastPart = GetLastItem( + result, + parts + // + ); + if (!hasLastPart) + { + // + result = mType; + return result; + } + + // + return result; + } + + // + // Pricate ... +private: + // + // Props ... + + // + string mPath; // Path + string mFileName; // Data Store File Name + + // + // Tools ... + + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } + + // + // Retrieve Data Store File Address ... + string GetStorePath() + { + // + string result = NULL; + + // + result = GetFilePath(mFileName); + + // + return result; + } +}; + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xea.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xea.class.mq5 new file mode 100644 index 0000000..d85c6ec --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xea.class.mq5 @@ -0,0 +1,4041 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseEA +// Description: provides all Base EA requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Classes/x-saherelm.xalert.class.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +// Define On Signal Event Handler Type ... +typedef void (*TOnSignal)(XSignal &signals[]); + +// +// Tokens ... +string XINProfitToken = "INP"; +string XINDrawdownToken = "IND"; +string XProfitsToken = "PFS"; +string XTimesToken = "TMS"; +string XPricessToken = "PCS"; + +// +enum ENUM_X_PROFIT_TRACK_FIELDS +{ + X_PROFIT_TRACK_PROFIT, + X_PROFIT_TRACK_LONGS_PROFIT, + X_PROFIT_TRACK_SHORTS_PROFIT, +}; + +// +// Model Account Profits ... +struct XProfitTrack +{ + // + int longs; // Number of Long ... + int shorts; // Number of Short ... + + // + double profit; // Profit of All ... + double longsProfit; // Profits of Longs ... + double shortsProfit; // Profits of Shorts ... + + // + double profitFrom; // Profit of All ... + double longsProfitFrom; // Profits of Longs ... + double shortsProfitFrom; // Profits of Shorts ... + + // + double volume; // Volume ... + double longsVolume; // Volume of Longs ... + double shortsVolume; // Volume of Shorts ... + + // + datetime time; // Check Time ... + + // + XProfitTrack() + { + Clean(); + } + + // + // Tools ... + + // + // Initialization ... + bool Init(XSCTrade *mTrader) + { + // + bool result = false; + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + result = positionsCount > 0; + if (!result) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isLong = IsLong(iPosition.type); + + // + if (isLong) + { + // + longs++; + longsVolume += iPosition.volume; + longsProfit += iPosition.profit; + } + else + { + // + shorts++; + shortsVolume += iPosition.volume; + shortsProfit += iPosition.profit; + } + + // + profit += iPosition.profit; + volume += iPosition.volume; + } + + // + result = IsValid(); + if (result) + { + time = TimeCurrent(); + } + + // + return result; + } + + // + double SelectField(ENUM_X_PROFIT_TRACK_FIELDS field) + { + // + double result = profit; + + // + switch (field) + { + // + case X_PROFIT_TRACK_LONGS_PROFIT: + result = longsProfit; + break; + + // + case X_PROFIT_TRACK_SHORTS_PROFIT: + result = shortsProfit; + break; + + // + default: + case X_PROFIT_TRACK_PROFIT: + result = profit; + break; + } + + // + return result; + } + + // + // Cleanup ... + void Clean() + { + // + longs = 0; + shorts = 0; + profit = 0; + volume = 0; + profitFrom = 0; + longsVolume = 0; + longsProfit = 0; + shortsVolume = 0; + shortsProfit = 0; + longsProfitFrom = 0; + shortsProfitFrom = 0; + + // + time = NULL; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + (longs > 0 || shorts > 0) + // + && + // + volume > 0 + // + ; + + // + return result; + } + + // +}; + +// +// Track Specific Position ... +struct XPositionTrack +{ + // + ulong ticket; // Position Ticket + string symbol; // Position Symbol + ENUM_POSITION_TYPE type; // Position Type + ENUM_TIMEFRAMES period; // Position Period + + // + double price[]; // Check Price ... + double profit[]; // Check Profit ... + datetime time[]; // Check Time ... + + // + double tp; // Current TP + double sl; // Current SL + double volume; // Current Volume + double entry; // Position Entry + datetime openAt; // Position Open Time + + // + int inProfitCount; // Number of Cross in DrawDown + int inDrawdownCount; // Number of Crossed in Profit + + // + // Constructor ... + XPositionTrack() + { + Clean(); + } + + // + // Tools ... + + // + // Initialization ... + bool Init( + XPosition &position // Source Position + ) + { + // + bool result = false; + + // + Clean(); + + // + result = position.IsValid(); + if (!result) + { + return result; + } + + // + ticket = position.ticket; + symbol = position.symbol; + period = position.period; + type = position.type; + tp = position.tp; + sl = position.sl; + entry = position.entry; + volume = position.volume; + openAt = position.openAt; + + // + datetime cTime = TimeCurrent(); + Add( + cTime, + time // + ); + + // + Add( + position.profit, + profit // + ); + + // + Add( + position.price, + price // + ); + + // + result = IsValid(); + + // + return result; + } + + // + bool Update( + XPosition &position // Source Position + ) + { + // + bool result = false; + + // + // Check Current Model is Valid or not ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Check Position is a Valid Model ... + result = position.IsValid(); + if (!result) + { + return result; + } + + // + // Check Current Model belongs to Given Position ... + result = + // + entry == position.entry && + openAt == position.openAt && + symbol == position.symbol && + period == position.period && + type == position.type && + ticket == position.ticket + // + ; + if (!result) + { + return result; + } + + // + tp = position.tp; + sl = position.sl; + volume = position.volume; + + // + datetime cTime = TimeCurrent(); + + // + SetArrayStates(false); + + // + Add( + cTime, + time // + ); + + // + Add( + position.profit, + profit // + ); + + // + Add( + position.price, + price // + ); + + // + SetArrayStates(true); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + // Fill In Profit or Drawdown Counters ... + + // + bool isCrossInProfit = IsCrossedInProfit(); + if (isCrossInProfit) + { + inProfitCount++; + } + + // + bool isCrossedInDrawdown = IsCrossedInDrawdown(); + if (isCrossedInDrawdown) + { + inDrawdownCount++; + } + + // + return result; + } + + // + // Cleanup ... + void + Clean() + { + // + ticket = 0; + type = NULL; + symbol = NULL; + period = NULL; + + // + tp = 0; + sl = 0; + volume = 0; + entry = 0; + openAt = NULL; + + // + inProfitCount = 0; + inDrawdownCount = 0; + + // + Clean(price); + Clean(profit); + Clean(time); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + ticket > 0 && + type != NULL && + period != NULL && + volume > 0 && + entry > 0 && + openAt > 0 + // + ; + + // + return result; + } + + // + void SetArrayStates(bool state) + { + // + ArraySetAsSeries(price, state); + ArraySetAsSeries(profit, state); + ArraySetAsSeries(time, state); + } + + // + bool IsCrossedInProfit() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = ArraySize(time) > 1; + if (!result) + { + return result; + } + + // + result = + // + profit[0] > 0 && + profit[1] < 0 + // + ; + + // + return result; + } + + // + bool IsCrossedInDrawdown() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = ArraySize(time) > 1; + if (!result) + { + return result; + } + + // + result = + // + profit[0] < 0 && + profit[1] > 0 + // + ; + + // + return result; + } + + // + // Collector Tools ... + + // + string GetToken() + { + return GetToken(this); + } + + // + bool IsModelValid() + { + return IsValid(); + } + + // + bool IsSameAs(XPositionTrack &track) + { + // + bool result = false; + + // + result = + // + track.IsValid() && + type == track.type && + ticket == track.ticket && + symbol == track.symbol && + period == track.period && + openAt == track.openAt + // + ; + + // + return result; + } + + // + int FindIndex( + const XPositionTrack &values[] // Collection + ) + { + // + return FindIndex( + this, + values + // + ); + } + + // + // Converts a Model to String Representation ... + string ToModelString() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + // For Modeling a PositionTrack Object ... + // - tp + // - sl + // - type + // - entry + // - ticket + // - symbol + // - period + // - openAt + // - volume + // - inProfitCount + // - inDrawdownCount + // - time[] + // - price[] + // - profit[] + + // + // Ticket ... + string ticketStr = Surround(XIDToken, ticket); + + // + // Symbol ... + string SymbolStr = Surround(XSymbolToken, symbol); + + // + // Type ... + string typeStr = Surround(XTypeToken, type); + + // + // Period ... + int iPeriodInt = (int)period; + string periodStr = Surround(XPeriodToken, iPeriodInt); + + // + // TP ... + string tpStr = Surround(XTPToken, tp); + + // + // SL ... + string slStr = Surround(XSLToken, sl); + + // + // Volume ... + string volumeStr = Surround(XVolumeToken, volume); + + // + // Entry ... + string entryStr = Surround(XEntryToken, entry); + + // + // OpenAt ... + string timeStr = Surround(XTimeToken, openAt); + + // + // InProfitCount ... + string inProfitCountStr = Surround(XINProfitToken, inProfitCount); + + // + // InDrawdownCount ... + string inDrawdownCountStr = Surround(XINDrawdownToken, inDrawdownCount); + + // + // Time(s) ... + string timesContentStr = ToString(time); + string timesStr = Surround(XTimesToken, timesContentStr); + + // + // Price(s) ... + string pricesContentStr = ToString(price); + string pricesStr = Surround(XPricessToken, pricesContentStr); + + // + // Profit(s) ... + string profitsContentStr = ToString(profit); + string profitsStr = Surround(XProfitsToken, profitsContentStr); + + // + string token = GetToken(); + + // + result = + // + token + + "[" + + // + ticketStr + + SymbolStr + + typeStr + + periodStr + + tpStr + + slStr + + volumeStr + + entryStr + + timeStr + + inProfitCountStr + + inDrawdownCountStr + + timesStr + + pricesStr + + profitsStr + + // + "]" + // + ; + + // + return result; + } + + // + // Pres and Fill Model based on it's String Representation ... + bool ParseModel(string value) + { + // + bool result = false; + + // + Clean(); + + // + result = IsValid(value); + if (!result) + { + return result; + } + + // + // For Modeling a PositionTrack Object ... + // - tp + // - sl + // - type + // - entry + // - ticket + // - symbol + // - period + // - openAt + // - volume + // - inProfitCount + // - inDrawdownCount + // - time[] + // - price[] + // - profit[] + + // + // TP ... + tp = ParseDoubleSurrounded(value, XTPToken); + + // + // SL ... + tp = ParseDoubleSurrounded(value, XSLToken); + + // + // Type ... + type = ((ENUM_POSITION_TYPE)ParseIntSurrounded(value, XTypeToken)); + + // + // Entry ... + entry = ParseDoubleSurrounded(value, XEntryToken); + + // + // Ticket ... + ticket = ParseLongSurrounded(value, XIDToken); + + // + // Symbol ... + symbol = ParseStringSurrounded(value, XSymbolToken); + + // + // Period ... + period = ((ENUM_TIMEFRAMES)ParseIntSurrounded(value, XPeriodToken)); + + // + // Open At ... + openAt = ParseTimeSurrounded(value, XTimeToken); + + // + // Volume ... + volume = ParseDoubleSurrounded(value, XVolumeToken); + + // + // InProfitCount ... + inProfitCount = ParseIntSurrounded(value, XINProfitToken); + + // + // InDrawdownCount ... + inDrawdownCount = ParseIntSurrounded(value, XINDrawdownToken); + + // + // Time(s) ... + ParseTimeArraySurrounded( + time, + value, + XTimesToken + // + ); + + // + // Price(s) ... + ParseDoubleArraySurrounded( + price, + value, + XPricessToken + // + ); + + // + // Profit(s) ... + ParseDoubleArraySurrounded( + profit, + value, + XProfitsToken + // + ); + + // + result = IsValid(); + + // + return result; + } +}; + +// +// Type Definitions for XPosition Tracker Events ... +typedef void (*TOnPositionState)(const XPositionTrack &track); + +// +// an Struct for Holding Event Handled Items for Position Tracker ... +struct XPositionTrackerState +{ + // + XPositionTrack inProfits[]; + XPositionTrack inDrawdowns[]; + + // + XPositionTrack onProfits[]; + XPositionTrack onDrawdowns[]; + + // + XPositionTrackerState() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + Clean(inProfits); + Clean(inDrawdowns); + + // + Clean(onProfits); + Clean(onDrawdowns); + } +}; + +// +// Position Tracker Class ... +class XSCPositionTracker +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + void XSCPositionTracker(bool cleanStore = false) + { + // + XSCDataCollector mBase; + + // + if (cleanStore) + { + mBase.Clear(); + } + } + + // + // Tools ... + + // + // Cleaning Store ... + void Clear() + { + // + XSCDataCollector mBase; + + // + mBase.Clear(); + } + + // + // Collect All Store ... + int Collect(XPositionTrack &result[]) + { + // + int mResult = 0; + + // + XSCDataCollector mBase; + + // + mResult = mBase.Collect(result); + + // + return mResult; + } + + // + // Add Item To Store ... + bool Add(XPositionTrack &item) + { + // + bool result = false; + + // + XSCDataCollector mBase; + + // + result = mBase.Add(item); + + // + return result; + } + + // + // Add Item(s) To Store ... + int Add(XPositionTrack &items[]) + { + // + int result = 0; + + // + XSCDataCollector mBase; + + // + result = mBase.Add(items); + + // + return result; + } + + // + // Remove an Item from Store ... + bool Remove(XPositionTrack &item) + { + // + bool result = false; + + // + XSCDataCollector mBase; + + // + result = mBase.Remove(item); + + // + return result; + } + + // + // Custom Functions ... + + // + // Sync all Content using Specific Trader Class ... + int Sync( + XPositionTrackerState &state, // Hold all Changes State ... + XSCTrade *mTrader // XSCTrade Instance for Synchronize ... + ) + { + // + int result = 0; + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + + // + ulong trackTickets[]; + XPositionTrack trackers[]; + int trackersCount = Collect(trackers); + + // + // Nothing to Do ... + if (positionsCount <= 0 && trackersCount <= 0) + { + return result; + } + + // + // Collect Exists Trackers Ticket's For Managing ... + for (int i = 0; i < trackersCount; i++) + { + // + XPositionTrack iTrack = trackers[i]; + + // + bool isValid = iTrack.IsValid(); + if (isValid) + { + // + AddSpecific( + iTrack.ticket, + trackTickets // + ); + } + } + + // + // Clear Tracker Store for Update Later ... + Clear(); + + // + // Collect All Required to Add/Update Trackers here ... + XPositionTrack syncedTracks[]; + + // + // a Flag for Synchronization Performance ... + bool hasTracker = trackersCount > 0; + + // + // Loop through Position for Managing Trackers ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // if there isn't any Track before ... + if (!hasTracker) + { + // + XPositionTrack iTrack; + bool isInited = iTrack.Init(iPosition); + if (isInited) + { + // + AddRef( + iTrack, + syncedTracks // + ); + + // + FillState( + iTrack, + state // + ); + } + + // + continue; + } + + // + // if there was some tracks ... + + // + // Try to Find Position Ticket in Track Tickets ... + int iTicketIdx = FindIndex( + iPosition.ticket, + trackTickets // + ); + bool isTrackedBefore = iTicketIdx >= 0; + + // + // Add new Track ... + if (!isTrackedBefore) + { + // + XPositionTrack iTrack; + bool isInited = iTrack.Init(iPosition); + if (isInited) + { + // + AddRef( + iTrack, + syncedTracks // + ); + + // + FillState( + iTrack, + state // + ); + } + } + // + // Update Exists Track ... + else + { + // + XPositionTrack iTrack = trackers[iTicketIdx]; + bool isUpdated = iTrack.Update(iPosition); + if (isUpdated) + { + // + AddRef( + iTrack, + syncedTracks // + ); + + // + FillState( + iTrack, + state // + ); + } + } + } + + // + // Check Synced Tracks ... + int syncedTracksCount = ArraySize(syncedTracks); + if (syncedTracksCount <= 0) + { + return result; + } + + // + result = Add(syncedTracks); + + // + return result; + } + + // + // Event Handlers ... + + // + // Add Profit Event Handler ... + void AddOnProfitEventHandler(TOnPositionState handler) + { + // + AddSpecific( + handler, + mOnProfitEventHandlers // + ); + } + + // + // Add Drawdown Event Handler ... + void AddOnDrawdownEventHandler(TOnPositionState handler) + { + // + AddSpecific( + handler, + mOnDrawdownEventHandlers // + ); + } + + // + // Protected ... +protected: + // + // Tools ... + + // + // Event Handlers ... + + // + // OnProfit ... + void NotifyOnProfitEvent(XPositionTrack &track) + { + // + int count = ArraySize(mOnProfitEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnPositionState iHandler = mOnProfitEventHandlers[i]; + iHandler(track); + } + } + + // + // OnDrawdown ... + void NotifyOnDrawdownEvent(XPositionTrack &track) + { + // + int count = ArraySize(mOnDrawdownEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnPositionState iHandler = mOnDrawdownEventHandlers[i]; + iHandler(track); + } + } + + // + // Private ... +private: + // + // Props ... + + // + TOnPositionState mOnProfitEventHandlers[]; + TOnPositionState mOnDrawdownEventHandlers[]; + + // + void FillState( + XPositionTrack &track, + XPositionTrackerState &state // + ) + { + // + // In Profit ... + bool isInProfit = track.profit[0] > 0; + if (isInProfit) + { + // + AddRef( + track, + state.inProfits // + ); + } + + // + // In Drawdown ... + bool isInDrawdown = track.profit[0] < 0; + if (isInDrawdown) + { + // + AddRef( + track, + state.inDrawdowns // + ); + } + + // + // On Profit ... + bool isOnProfit = track.IsCrossedInProfit(); + if (isOnProfit) + { + // + AddRef( + track, + state.onProfits // + ); + } + + // + // On Drawdown ... + bool isOnDrawdown = track.IsCrossedInDrawdown(); + if (isOnDrawdown) + { + // + AddRef( + track, + state.onDrawdowns // + ); + } + } +}; + +// +class XSCPositionHolder +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + + // + XSCPositionHolder() + { + Clear(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clear() + { + Clean(mItems); + } + + // + bool AddItem(XPosition &item) + { + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + result = !HasItem(item); + if (!result) + { + return result; + } + + // + AddRef( + item, + mItems // + ); + + // + return result; + } + + // + int AddItems(XPosition &items[]) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + bool isAdded = AddItem(iItem); + if (isAdded) + { + result++; + } + } + + // + return result; + } + + // + bool AddOrUpdateItem(XPosition &item) + { + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + bool hasItem = HasItem(item); + if (!hasItem) + { + result = AddItem(item); + } + else + { + // + result = RemoveItem(item); + if (result) + { + result = AddItem(item); + } + } + + // + return result; + } + + // + int AddOrUpdateItem(XPosition &items[]) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + bool isAddOrUpdated = AddOrUpdateItem(iItem); + if (isAddOrUpdated) + { + result++; + } + } + + // + return result; + } + + // + bool HasItem(XPosition &item) + { + // + bool result = false; + + // + int itemIDX = FindItem(item); + result = itemIDX >= 0; + + // + return result; + } + + // + int FindItem(XPosition &item) + { + // + int result = -1; + + // + if (!item.IsValid()) + { + return result; + } + + // + int itemsCount = CountItems(); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isSame = IsItemSameAs(item, iItem); + if (isSame) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + bool GetByIndex( + int index, + XPosition &item // + ) + { + // + bool result = false; + + // + NormalizeIndex( + index, + mItems // + ); + + // + item = mItems[index]; + + // + result = item.IsValid(); + + // + return result; + } + + // + bool RemoveItem(XPosition &item) + { + // + bool result = false; + + // + result = HasItem(item); + if (!result) + { + return result; + } + + // + int itemIDX = FindItem(item); + result = ArrayRemove( + mItems, + itemIDX, + 1 // + ); + + // + return result; + } + + // + int RemoveItems(XPosition &items[]) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + bool isRemoved = RemoveItem(iItem); + if (isRemoved) + { + result++; + } + } + + // + return result; + } + + // + int CountItems() + { + return ArraySize(mItems); + } + + // + bool IsItemSameAs( + XPosition &source, + XPosition &dest // Compare Source with this ... + ) + { + // + bool result = false; + + // + result = + // + dest.IsValid() && + source.IsValid() && + source.symbol == dest.symbol && + source.period == dest.period && + source.ticket == dest.ticket && + source.openAt == dest.openAt && + source.provider == dest.provider + // + ; + + // + return result; + } + + // + // Custom Functions ... + + // + bool GetMaxInDrawdown( + XPosition &item // Result + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + int maxIDX = -1; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool canSelect = + // + iItem.profit < 0 + // + && + // + ( + // + (maxIDX == -1 && !item.IsValid()) + ? true + : item.profit < iItem.profit + // + ) + // + ; + if (canSelect) + { + // + maxIDX = i; + item = iItem; + } + } + + // + result = maxIDX > -1 && item.IsValid(); + + // + return result; + } + + // + bool GetMaxInProfit( + XPosition &item // Result + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + int maxIDX = -1; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool canSelect = + // + iItem.profit > 0 + // + && + // + ( + // + (maxIDX == -1 && !item.IsValid()) + ? true + : item.profit < iItem.profit + // + ) + // + ; + if (canSelect) + { + // + maxIDX = i; + item = iItem; + } + } + + // + result = maxIDX > -1 && item.IsValid(); + + // + return result; + } + + // + bool GetFarestEntry( + XPosition &item, // Result + string symbol = NULL, + string provider = NULL, + ENUM_TIMEFRAMES period = NULL, + ENUM_POSITION_TYPE type = NULL // + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isFiltersPassed = + // + iItem.IsFiltersPassed( + symbol, + provider, + period, + type // + ) + // + ; + + // + if (!isFiltersPassed) + { + continue; + } + + // + // Do Additional Filtering ... + bool isValidEntry = + // + !item.IsValid() + ? true + : item.entry < iItem.entry + // + ; + if (isValidEntry) + { + // + item = iItem; + } + } + + // + result = item.IsValid(); + + // + return result; + } + + // + bool GetNearestEntry( + XPosition &item, // Result + string symbol = NULL, + string provider = NULL, + ENUM_TIMEFRAMES period = NULL, + ENUM_POSITION_TYPE type = NULL // + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isFiltersPassed = + // + iItem.IsFiltersPassed( + symbol, + provider, + period, + type // + ) + // + ; + + // + if (!isFiltersPassed) + { + continue; + } + + // + // Do Additional Filtering ... + bool isValidEntry = + // + !item.IsValid() + ? true + : item.entry > iItem.entry + // + ; + if (isValidEntry) + { + // + item = iItem; + } + } + + // + result = item.IsValid(); + + // + return result; + } + + // + bool GetFarestSL( + XPosition &item, // Result + string symbol = NULL, + string provider = NULL, + ENUM_TIMEFRAMES period = NULL, + ENUM_POSITION_TYPE type = NULL // + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isFiltersPassed = + // + iItem.IsFiltersPassed( + symbol, + provider, + period, + type // + ) + // + ; + + // + if (!isFiltersPassed) + { + continue; + } + + // + // Do Additional Filtering ... + bool isValidEntry = + // + !item.IsValid() + ? true + : item.sl < iItem.sl + // + ; + if (isValidEntry) + { + // + item = iItem; + } + } + + // + result = item.IsValid(); + + // + return result; + } + + // + bool GetNearestSL( + XPosition &item, // Result + string symbol = NULL, + string provider = NULL, + ENUM_TIMEFRAMES period = NULL, + ENUM_POSITION_TYPE type = NULL // + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isFiltersPassed = + // + iItem.IsFiltersPassed( + symbol, + provider, + period, + type // + ) + // + ; + + // + if (!isFiltersPassed) + { + continue; + } + + // + // Do Additional Filtering ... + bool isValidEntry = + // + !item.IsValid() + ? true + : item.sl > iItem.sl + // + ; + if (isValidEntry) + { + // + item = iItem; + } + } + + // + result = item.IsValid(); + + // + return result; + } + + // + bool GetFarestTP( + XPosition &item, // Result + string symbol = NULL, + string provider = NULL, + ENUM_TIMEFRAMES period = NULL, + ENUM_POSITION_TYPE type = NULL // + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isFiltersPassed = + // + iItem.IsFiltersPassed( + symbol, + provider, + period, + type // + ) + // + ; + + // + if (!isFiltersPassed) + { + continue; + } + + // + // Do Additional Filtering ... + bool isValidEntry = + // + !item.IsValid() + ? true + : item.tp < iItem.tp + // + ; + if (isValidEntry) + { + // + item = iItem; + } + } + + // + result = item.IsValid(); + + // + return result; + } + + // + bool GetNearestTP( + XPosition &item, // Result + string symbol = NULL, + string provider = NULL, + ENUM_TIMEFRAMES period = NULL, + ENUM_POSITION_TYPE type = NULL // + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isFiltersPassed = + // + iItem.IsFiltersPassed( + symbol, + provider, + period, + type // + ) + // + ; + + // + if (!isFiltersPassed) + { + continue; + } + + // + // Do Additional Filtering ... + bool isValidEntry = + // + !item.IsValid() + ? true + : item.tp > iItem.tp + // + ; + if (isValidEntry) + { + // + item = iItem; + } + } + + // + result = item.IsValid(); + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + XPosition mItems[]; +}; + +// +// Class Definition ... + +class XSCBaseEA : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + XSCBaseEA( + // + // XTrade Class Requirements ... + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + int manageInterval, // Manager Check Intervals Seconds + double maxAllowedSpread, // Max Allowed Spred for Opening Trades + int maxAllowedPositions, // Max Allowed Positions + double maxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + double staticVolume, // Static Volume for Positions + // + // Position Management ... + bool allowLong = true, // Allow Long Trades + bool allowShort = true, // Allow Short Trades + double minProfitPerTrade = 0, // Min Profit Per Trade based On Volume Factor (Hedge) + double minProfitPerVolumeFactor = 0, // Min Volume Factor for Calculating Profit (Hedge) + // + // Event Handlers ... + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL, // On Trade State Changed Event Handler + // + // Log Handler ... + bool enableAlerts = true, // Enable Alerts + bool logAlerts = true, // Log Alerts + bool terminalAlerts = false, // Terminal Alerts + bool mailAlerts = false, // Mail Alerts + bool pushAlerts = false // Push Alerts + ) + { + // + // Instance XSCTrade Class ... + mTrader = new XSCTrade( + slippage, + magicNumber, + manageInterval, + maxAllowedSpread, + maxAllowedPositions, + maxAllowedDrawdownFactor + // + ); + + // + mIsInTestMode = IsRunningOnTestMode(); + + // + // Position Management ... + mAllowLong = allowLong; + mAllowShort = allowShort; + mMinProfitPerTrade = minProfitPerTrade; + mMinProfitPerVolumeFactor = minProfitPerVolumeFactor; + mStaticVolume = staticVolume; + + // + // Set Event Handlers ... + mOnStopLossTriggered = onStopLossTriggered; + mOnTakeProfitTriggered = onTakeProfitTriggered; + mOnDealsChangedHandler = onDealsChangedHandler; + mOnOrdersChangedHandler = onOrdersChangedHandler; + mOnPositionsChangedHandler = onPositionsChangedHandler; + mOnTradeStateChangedHandler = onTradeStateChangedHandler; + + // + // Add Event Listeners to XTrade Class if they Provided ... + if (mOnStopLossTriggered != NULL) + { + mTrader.AddOnStopLossEventHandler(mOnStopLossTriggered); + } + + // + if (mOnTakeProfitTriggered != NULL) + { + mTrader.AddOnTakeProfitEventHandler(mOnTakeProfitTriggered); + } + + // + if (mOnDealsChangedHandler != NULL) + { + mTrader.AddOnDealsChangedEventHandler(mOnDealsChangedHandler); + } + + // + if (mOnOrdersChangedHandler != NULL) + { + mTrader.AddOnOrdersChangedEventHandler(mOnOrdersChangedHandler); + } + + // + if (mOnPositionsChangedHandler != NULL) + { + mTrader.AddOnPositionsChangedEventHandler(mOnPositionsChangedHandler); + } + + // + if (mOnTradeStateChangedHandler != NULL) + { + mTrader.AddOnTradeStateChangedEventHandler(mOnTradeStateChangedHandler); + } + + // + // Instantiate Alert Class ... + mAlert = new XSCAlert( + GetTag(), + enableAlerts, + logAlerts, + terminalAlerts, + mailAlerts, + pushAlerts + // + ); + + // + // Instantiate XPositionTracker Class ... + mPositionTracker = new XSCPositionTracker(); + + // + // Do Synchronisation after Instantiate everything ... + XPositionTrackerState state; + mPositionTracker.Sync( + state, + mTrader // + ); + } + + // + // Deconstractor ... + ~XSCBaseEA() + { + // + delete mTrader; + delete mAlert; + delete mPositionTracker; + } + + // + // Properties Getter(s) / Setter(s) ... + + // + // Retrieve Slippage ... + int GetSlippage() + { + return mTrader.GetSlippage(); + } + + // + // Retrieve Magic Number ... + ulong GetMagicNumber() + { + return mTrader.GetMagicNumber(); + } + + // + // Retrieve Max Allowed Spread for Trading ... + double GetMaxAllowedSpread() + { + return mTrader.GetMaxAllowedSpread(); + } + + // + // Retrieve Max Allowed Same Time Positions Count ... + int GetMaxAllowedPositions() + { + return mTrader.GetMaxAllowedPositions(); + } + + // + // Retrieve Max Allowed Drawdown for Opening new Trades ... + double GetMaxAllowedDrawdownFactor() + { + return mTrader.GetMaxAllowedDrawdownFactor(); + } + + // + double GetStaticVolume() + { + return mStaticVolume; + } + + // + void SetStaticVolume(double value) + { + // + if (value <= 0) + { + value = 0.01; + } + + // + mStaticVolume = value; + } + + // + bool GetAllowLong() + { + return mAllowLong; + } + + // + void SetAllowLong(bool value) + { + mAllowLong = value; + } + + // + bool GetAllowShort() + { + return mAllowShort; + } + + // + void SetAllowShort(bool value) + { + mAllowShort = value; + } + + // + double GetMinProfitPerTrade() + { + return mMinProfitPerTrade; + } + + // + void SetMinProfitPerTrade(double value) + { + // + if (value <= 0) + { + value = 0; + } + + // + if (value == mMinProfitPerTrade) + { + return; + } + + // + mMinProfitPerTrade = value; + } + + // + double GetMinProfitPerVolumeFactor() + { + return mMinProfitPerVolumeFactor; + } + + // + void SetMinProfitPerVolumeFactor(double value) + { + // + if (value <= 0) + { + value = 0; + } + + // + if (value == mMinProfitPerVolumeFactor) + { + return; + } + + // + mMinProfitPerVolumeFactor = value; + } + + // + bool IsHedgeEnable() + { + // + bool result = + // + mMinProfitPerTrade > 0 && + mMinProfitPerVolumeFactor > 0 + // + ; + + // + return result; + } + + // + // Alert ... + + // + bool GetLogAlerts() + { + return mAlert.GetLogAlerts(); + } + + // + void SetLogAlerts(bool value) + { + mAlert.SetLogAlerts(value); + } + + // + bool GetEnableAlerts() + { + return mAlert.GetEnableAlerts(); + } + + // + void SetEnableAlerts(bool value) + { + mAlert.SetEnableAlerts(value); + } + + // + bool GetPushAlerts() + { + return mAlert.GetPushAlerts(); + } + + // + void SetPushAlerts(bool value) + { + mAlert.SetPushAlerts(value); + } + + // + bool GetMailAlerts() + { + return mAlert.GetMailAlerts(); + } + + // + void SetMailAlerts(bool value) + { + mAlert.SetMailAlerts(value); + } + + // + bool GetTerminalAlerts() + { + return mAlert.GetTerminalAlerts(); + } + + // + void SetTerminalAlerts(bool value) + { + mAlert.SetTerminalAlerts(value); + } + + // + void SetAlertPrefix(string value) + { + mAlert.SetPrefix(value); + } + + // + // Event Listeners ... + void AddOnSignalEventHandler(TOnSignal listener) + { + // + Add( + listener, + mOnSignalEventHandlers + // + ); + } + + // + // Alert Functions ... + + // + // Logging an Alert ... + void LogAlert(string message) + { + mAlert.LogAlert(message); + } + + // + // Terminal Alert ... + void TerminalAlert(string message) + { + mAlert.TerminalAlert(message); + } + + // + // Mail Alert ... + void MailAlert(string message) + { + mAlert.MailAlert(message); + } + + // + // Send Push Notification ... + void PushAlert(string message) + { + mAlert.PushAlert(message); + } + + // + // Send an Alert by Handling all Different Specified + // type's of Alert's if they are Enabled ... + void Alert(string message) + { + mAlert.Alert(message); + } + + // + // Overrides ... + + // + // Customize Token ... + virtual string GetToken() + { + return GetSpecificToken(this); + } + + // + virtual string GetTag() + { + return this.GetToken(); + } + + // + // Virtual Functions ... + + // + // Handle Chart Events ... + virtual void OnChartEvent( + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter + ) + { + } + + // + // OnTick Handler ... + virtual void OnTick() + { + // + // Draw ... + Draw(); + + // + // Check Trade Events ... + OnTrade(); + + // + HandleProfitManageMent(); + + // + // First Check For Any Guard Actions ... + // then Handle Guards if Provided ... + XGuard guards[]; + bool hasGuard = CheckForGuard(guards); + if (hasGuard) + { + DoGuards(guards); + } + + // + XSignal signals[]; + + // + // Second Check for Position Management or Equity Management + // Actions like Supports or etc ... + bool isIgnored = HandleStateManagement(signals); + if (isIgnored) + { + return; + } + + // + // Second Check For Signals ... + // then Execute Signals if Provided ... + int signalsCount = RequestForSignal(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Execute Signals ... + HandleSignalsExecution(signals); + } + + // + // Handle StopLoss Event ... + virtual void OnStopLossTriggered(const XDeal &deal) {} + + // + // Handle TakeProfit Event ... + virtual void OnTakeProfitTriggered(const XDeal &deal) {} + + // + // Handle Deals Changed Event ... + virtual void OnDealsChangedHandler(int count) {} + + // + // Handle Order Changed Event ... + virtual void OnOrdersChangedHandler(int count) {} + + // + // Handle Position Changed Event ... + virtual void OnPositionsChangedHandler(int count) {} + + // + // Handle Trade State Changed ... + virtual void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) {} + + // + // Handle On Trade ... + virtual void OnTrade() + { + // + XOnTradeHandlerState state = mTrader.HandleOnTrade(); + + // + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + OnTradeStateChangedHandler(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + OnDealsChangedHandler(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + mTrader.GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + OnTakeProfitTriggered(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + OnStopLossTriggered(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + OnOrdersChangedHandler(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + OnPositionsChangedHandler(state.newPositions); + } + } + + // + // Retrieve Dept Of Market ... + virtual void OnBookEvent(const string &symbol) + { + // + // TODO: Implement this ... + } + + // + // Draw On Chart if anything is required ... + virtual void Draw() {} + + // + // Check For any Guard Actions ... + virtual bool CheckForGuard(XGuard &guards[]) + { + return false; + } + + // + // When a Guard Notified to Do Support Signal ... + // this Method Calls For Retrieve Support Signal ... + // if it's Provided, Execute it ... + virtual bool RequestForSupport( + XSignal &support, // Holds Support Signal, if Provided + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + return false; + } + + // + // Handle Position(s)/ Order(s) or EQM Supporting Action ... + // if returns false, prevent for process Tick ... + virtual bool HandleStateManagement(XSignal &signals[]) + { + return false; + } + + // + // Regulary Filtered Signals passed to this + // and here we can do Additional Signal Filtering + // for Signal Management such as (Providers and etc) ... + virtual int HandleSignalManagement(XSignal &signals[]) + { + // + int result = ArraySize(signals); + + // + return result; + } + + // + // Here we Have to Check Market based + // on our Strategy for Trading ... + // and if a Good Entry founded ... + // model it as an XSignal struct and passed it to result ... + virtual int RequestForSignal( + XSignal &signals[] // Holds Signals ... + ) + { + return 0; + } + + // + // When Some Errors happens in Executing Signals ... + virtual void ManageUnExecutedSignals( + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], + XSignal &unExecutedSignals[] // + ) + { + } + + // + // Execute Provided Signals ... + virtual void HandleSignalsExecution(XSignal &signals[]) + { + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Filter Signals Based on their Types ... + XSignal filteredSignals[]; + + // + // Try to Filter Signals ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isLong = IsLong(iSignal.type); + + // + if ((isLong && !GetAllowLong()) || (!isLong && !GetAllowShort())) + { + continue; + } + + // + AddRef( + iSignal, + filteredSignals // + ); + } + + // + int filteredSignalsCount = ArraySize(filteredSignals); + if (filteredSignalsCount <= 0) + { + return; + } + + // + int managedSignalsCount = HandleSignalManagement(filteredSignals); + if (managedSignalsCount <= 0) + { + return; + } + + // + // Try to Execute Signals ... + XSignal notExecuteds[]; + ENUM_X_SIGNAL_EXECUTION_RESULT reasons[]; + int executedSignalsCount = mTrader.ExecuteSpecifiedSignals( + filteredSignals, + notExecuteds, // Not Executed Signals + reasons + // + ); + + // + string message = NULL; + if (executedSignalsCount == 0) + { + // + message = "(" + ToString(filteredSignalsCount) + ") Signals Execution Failed ..."; + + // + for (int j = 0; j < ArraySize(reasons); j++) + { + // + string iReason = ToString(reasons[j]); + + // + message += "\n" + ToString(j) + ": " + iReason; + } + } + else if (executedSignalsCount < filteredSignalsCount) + { + // + int diff = filteredSignalsCount - executedSignalsCount; + + // + message = "Failed to Execute (" + ToString(diff) + ") Signals ..."; + } + else if (executedSignalsCount == filteredSignalsCount) + { + message = "(" + ToString(executedSignalsCount) + ") Signals Executed Successfully ..."; + } + + // + if (ArraySize(notExecuteds) > 0) + { + // + ManageUnExecutedSignals( + reasons, + notExecuteds // + ); + } + + // + if (IsValid(message)) + { + mAlert.Alert(message); + } + } + + // + virtual void OnGoingToProfit(XProfitTrack &track) {} + virtual void OnLongsGoingToProfit(XProfitTrack &track) {} + virtual void OnShortsGoingToProfit(XProfitTrack &track) {} + + // + virtual void OnGoingToDrawdown(XProfitTrack &track) {} + virtual void OnLongsGoingToDrawdown(XProfitTrack &track) {} + virtual void OnShortsGoingToDrawdown(XProfitTrack &track) {} + + // + virtual void OnPositionGoingInProfit(XPositionTrack &track) {} + virtual void OnPositionGoingToDrawdown(XPositionTrack &track) {} + + // + // Protected ... +protected: + // + // Props ... + + // + // Trade Class Instance ... + XSCTrade *mTrader; + XSCAlert *mAlert; + XSCPositionTracker *mPositionTracker; + + // + // Check in Test Mode or not ... + bool mIsInTestMode; + + // + // Tools ... + + // + // Signal Event Listeners ... + void NotifyOnSignalEventHandlers(XSignal &signals[]) + { + // + int listenersCount = ArraySize(mOnSignalEventHandlers); + if (listenersCount <= 0) + { + return; + } + + // + for (int i = 0; i < listenersCount; i++) + { + // + TOnSignal iListener = mOnSignalEventHandlers[i]; + + // + iListener(signals); + } + } + + // + // Position Management ... + + // + // Calculate Required Profit for Hedging ... + double CalculateRequiredProfitForHedge( + XPosition &positions[] // Source + ) + { + // + double result = SpecifiedCalculateRequiredProfitForHedge( + positions, + mMinProfitPerTrade, + mMinProfitPerVolumeFactor // + ); + + // + return result; + } + + // + // Calculate Positions Profit Summary ... + double CalculatePositionsProfit( + XPosition &positions[] // Source + ) + { + // + double result = SpecifiedCalculatePositionsProfit(positions); + + // + return result; + } + + // + // Profit Tracker ... + + // + XProfitTrack mProfitTracks[]; + + // + bool GetProfitTrack( + XProfitTrack &track, + int index = 0 // + ) + { + // + bool result = false; + + // + if (index < 0) + { + index = 0; + } + + // + int tracksCount = CountProfitTracks(); + result = tracksCount > 0 && index < tracksCount; + if (!result) + { + return result; + } + + // + track.Clean(); + + // + track = mProfitTracks[index]; + + // + result = track.IsValid(); + + // + return result; + } + + // + int CountProfitTracks() + { + return ArraySize(mProfitTracks); + } + + // + void AddProfitTrack() + { + // + XProfitTrack track; + bool isValid = track.Init(mTrader); + if (!isValid) + { + return; + } + + // + ArraySetAsSeries(mProfitTracks, false); + + // + AddRef( + track, + mProfitTracks // + ); + + // + ArraySetAsSeries(mProfitTracks, true); + } + + // + // Extract Specified Field Vales of XProfit Track Struct ... + int ExtractProfitTrackField( + double &result[], + ENUM_X_PROFIT_TRACK_FIELDS field, + int start = 0, + int count = 10 // + ) + { + // + Clean(result); + + // + if (start < 0) + { + start = 0; + } + + // + int end = start + count; + + // + int tracksCount = CountProfitTracks(); + if (end > tracksCount) + { + end = tracksCount; + } + + // + for (int i = start; i < end; i++) + { + // + XProfitTrack iTrack; + bool isValid = GetProfitTrack( + iTrack, + i // + ); + + // + if (!isValid) + { + continue; + } + + // + double iValue = iTrack.SelectField(field); + Add( + iValue, + result // + ); + } + + // + int mResult = ArraySize(result); + + // + return mResult; + } + + // + double AverageProfitTrackField( + ENUM_X_PROFIT_TRACK_FIELDS field, + int start = 0, + int count = 10 // + ) + { + // + double result = EMPTY_VALUE; + + // + double items[]; + int itemsCount = ExtractProfitTrackField( + items, + field, + start, + count // + ); + if (itemsCount <= 0) + { + return result; + } + + // + result = GetAverage(items); + + // + return result; + } + + // + bool IsProfitTrackFieldIncreasing( + ENUM_X_PROFIT_TRACK_FIELDS field, + int start = 0, + int count = 10 // + ) + { + // + bool result = false; + + // + double items[]; + int itemsCount = ExtractProfitTrackField( + items, + field, + start, + count // + ); + if (itemsCount <= 0) + { + return result; + } + + // + int from = itemsCount - 1; + int to = 0; + + // + result = IsIncreasing( + from, + to, + items // + ); + + // + return result; + } + + // + bool IsProfitTrackFieldDecreasing( + ENUM_X_PROFIT_TRACK_FIELDS field, + int start = 0, + int count = 10 // + ) + { + // + bool result = false; + + // + double items[]; + int itemsCount = ExtractProfitTrackField( + items, + field, + start, + count // + ); + if (itemsCount <= 0) + { + return result; + } + + // + int from = itemsCount - 1; + int to = 0; + + // + result = IsDecreasing( + from, + to, + items // + ); + + // + return result; + } + + // + void HandleProfitManageMent() + { + // + // Check Tracking Interval ... + + // + static datetime lastProfitTracked = NULL; + datetime cTime = TimeCurrent(); + + // + int profitManagementInterval = PeriodSeconds(PERIOD_M5); + int timeDiff = (int)cTime - (int)lastProfitTracked; + + // + bool canManage = + // + lastProfitTracked == NULL + ? true + : timeDiff >= profitManagementInterval + // + ; + if (!canManage) + { + return; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + // + Clean(mProfitTracks); + return; + } + + // + lastProfitTracked = cTime; + + // + // Do Track ... + + // + AddProfitTrack(); + + // + int profitsCount = CountProfitTracks(); + if (profitsCount <= 1) + { + return; + } + + // + XProfitTrack cT; + bool isValid = GetProfitTrack( + cT, + 0 // + ); + if (!isValid) + { + return; + } + + // + XProfitTrack pT; + isValid = GetProfitTrack( + pT, + 1 // + ); + if (!isValid) + { + return; + } + + // + cT.profitFrom = pT.profit; + cT.longsProfitFrom = pT.longsProfit; + cT.shortsProfitFrom = pT.shortsProfit; + + // + bool isGoningToProfit = + // + cT.profit > 0 && + pT.profit <= 0 + // + ; + if (isGoningToProfit) + { + // + OnGoingToProfit(cT); + } + + // + bool isLongsGoningToProfit = + // + cT.longsProfit > 0 && + pT.longsProfit <= 0 + // + ; + if (isLongsGoningToProfit) + { + OnLongsGoingToProfit(cT); + } + + // + bool isShortsGoningToProfit = + // + cT.shortsProfit > 0 && + pT.shortsProfit <= 0 + // + ; + if (isShortsGoningToProfit) + { + OnShortsGoingToProfit(cT); + } + + // + bool isGoningToDrawdown = + // + cT.profit < 0 && + pT.profit >= 0 + // + ; + if (isGoningToDrawdown) + { + OnGoingToDrawdown(cT); + } + + bool isLongsGoningToDrawdown = + // + cT.longsProfit < 0 && + pT.longsProfit >= 0 + // + ; + if (isLongsGoningToDrawdown) + { + OnLongsGoingToDrawdown(cT); + } + + bool isShortsGoningToDrawdown = + // + cT.shortsProfit < 0 && + pT.shortsProfit >= 0 + // + ; + if (isShortsGoningToDrawdown) + { + OnShortsGoingToDrawdown(cT); + } + } + + // + // Synchronize Positions and Position Tracker ... + void SyncPositionTracker() + { + // + // Check Syncing Interval ... + + // + static datetime lastSyncPositionTracker = NULL; + datetime cTime = TimeCurrent(); + + // + int syncInterval = PeriodSeconds(PERIOD_M5); + int lastDiff = (int)cTime - (int)lastSyncPositionTracker; + + // + bool canSync = + // + lastSyncPositionTracker == NULL + ? true + : lastDiff >= syncInterval + // + ; + if (!canSync) + { + return; + } + + // + lastSyncPositionTracker = cTime; + + // + // Do Sync ... + + // + XPositionTrackerState state; + int synced = mPositionTracker.Sync( + state, + mTrader // + ); + if (synced > 0) + { + // + // Check State and Do What we Want ... + int onProfitsCount = ArraySize(state.onProfits); + int onDrawdownCount = ArraySize(state.onDrawdowns); + + // + // Do What we want whe a Position Dropped to Prefit ... + if (onProfitsCount > 0) + { + // + for (int i = 0; i < onProfitsCount; i++) + { + // + XPositionTrack iTrack = state.onProfits[i]; + + // + OnPositionGoingInProfit(iTrack); + } + } + + // + // Do what we want when a Position Dropped to Drawdown ... + if (onDrawdownCount > 0) + { + // + for (int i = 0; i < onDrawdownCount; i++) + { + // + XPositionTrack iTrack = state.onDrawdowns[i]; + + // + OnPositionGoingToDrawdown(iTrack); + } + } + } + } + + // + // Guards ... + + // + // Do All Provided Guards ... + void DoGuards(XGuard &guards[]) + { + // + int guardsCount = ArraySize(guards); + if (guardsCount <= 0) + { + return; + } + + // + for (int i = 0; i < guardsCount; i++) + { + // + XGuard iGuard = guards[i]; + + // + switch (iGuard.action) + { + // + // Hedge In Profit Specified Positions ... + case X_GUARD_ACTION_HEDGE: + HandleGuardHedgeAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Trail Stop Loss in Specified Positions ... + case X_GUARD_ACTION_TRAIL_STOP: + HandleGuardTrailingStopAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period, + iGuard.dblPayLoad); + break; + + // + // Force Close Specified Positions ... + case X_GUARD_ACTION_FORCE_CLOSE: + HandleGuardForceCloseAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Generate and Place Support Signals ... + case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL: + HandleGuardAddSupportPositionAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Delete All Placed Pending Orders ... + case X_GUARD_ACTION_CANCEL_PENDING_ORDERS: + HandleGuardCancelPendingOrdersAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + } + } + } + + // + // Close All Specified Provider's Positions in Profit Summary ... + void HandleGuardHedgeAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double minProfitForHedging = 1 // Specified Profit for Hedge + ) + { + // + XPosition positions[]; + int positionsCount = mTrader + .GetPositions( + positions, + symbol, + provider, + period, + type + // + ); + if (positionsCount <= 1) + { + return; + } + + // + double profit = CalculatePositionsProfit(positions); + double requiredProfit = CalculateRequiredProfitForHedge(positions); + + // + bool isReadyForHedge = profit >= requiredProfit; + if (!isReadyForHedge) + { + return; + } + + // + string comment = "Guard Hedge " + provider; + int closed = mTrader.Close( + positions, + comment + // + ); + if (closed > 0) + { + // + string message = "Guard Hedge " + provider + "'s Positions on Profit: " + ToString(profit); + + // + mAlert.Alert(message); + } + } + + // + // Close Max In Profit Trade Guard Action ... + void HandleGuardCloseInProfitAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + int positionsCount = mTrader + .GetInProfitPositions( + positions, + symbol, + provider, + period, + type, + method + // + ); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InProfit ..."; + mTrader.Close( + positions, + comment + // + ); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Postion(s) In Profit ..."; + + // + mAlert.Alert(message); + } + + // + // Close Max In Drawdown Trade Guard Action ... + void HandleGuardCloseInDrawdownAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + int positionsCount = mTrader + .GetInDrawdownPositions( + positions, + symbol, + provider, + period, + type, + method + // + ); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InDrawdown ..."; + mTrader.Close( + positions, + comment + // + ); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Position(s) In Drawdown ..."; + + // + mAlert.Alert(message); + } + + // + // Force Close Specified Set Of Position ... + void HandleGuardForceCloseAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ulong ticket = 0 // Specific Ticket + ) + { + // + string comment = ""; + + // + // Close All Positions ... + if (ticket == 0) + { + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions, + symbol, + provider, + period, + type + // + ); + if (positionsCount <= 0) + { + return; + } + + // + comment = provider + " Force Close Guard ..."; + + // + mTrader.Close( + positions, + comment + // + ); + } + // + // Close Specific Position ... + else + { + // + XPosition position; + bool hasPosition = mTrader + .GetPosition( + ticket, + position + // + ); + + // + if (hasPosition) + { + // + comment = provider + "(" + ToString(ticket) + ")" + " Force Close Guard ..."; + + // + mTrader.Close( + ticket, + comment + // + ); + } + } + + // + if (IsValid(comment)) + { + mAlert.Alert(comment); + } + } + + // + // Trailing Specified Set Of Positions Stop Losses ... + void HandleGuardTrailingStopAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double sl // Desired SL Value ... + ) + { + // + if (sl <= 0) + { + return; + } + + // + NormalizePrice( + sl, + symbol + // + ); + + // + XPosition positions[]; + int positionsCount = mTrader + .GetPositions( + positions, + symbol, + provider, + period, + type + // + ); + if (positionsCount <= 0) + { + return; + } + + // + int modified = 0; + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string comment = PrepareSLTrailTag(iPosition.comment); + + // + if (iPosition.sl == sl) + { + continue; + } + + // + bool isModified = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp, + comment); + if (isModified) + { + modified++; + } + } + + // + if (modified > 0) + { + // + string message = "(" + ToString(modified) + ") Position's Stop Trailed Successfully ..."; + + // + mAlert.Alert(message); + } + } + + // + // Add Support Signal for Specified Positions ... + void HandleGuardAddSupportPositionAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + XSignal support; + bool hasSupport = RequestForSupport( + support, + provider, + symbol, + type, + period + // + ); + + // + if (!hasSupport || !support.IsValid()) + { + return; + } + + // + // TODO: May be need to add Support Tag to comments ... + + // + ENUM_X_SIGNAL_EXECUTION_RESULT reason = NULL; + bool isExecuted = mTrader.ExecuteSignal( + support, + reason); + + // + string comment = NULL; + if (!isExecuted) + { + comment = "Support Execution Failed doue " + ToString(reason); + } + else + { + comment = "Guard Support Signal Executed Successfully ..."; + } + + // + if (IsValid(comment)) + { + mAlert.Alert(comment); + } + } + + // + // Cancel all Placed Orders ... + void HandleGuardCancelPendingOrdersAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + XOrder orders[]; + int ordersCount = mTrader.GetOrders( + orders, + symbol, + provider, + period, + ToOrderType(type), + ORDER_STATE_PLACED, + true // Filter by Magic ... + // + ); + if (ordersCount <= 0) + { + return; + } + + // + int canceledOrdersCount = mTrader.CancelOrders(orders); + + // + if (canceledOrdersCount > 0) + { + // + string message = "Guard Cancel (" + ToString(canceledOrdersCount) + ") Pending Orders ..."; + + // + mAlert.Alert(message); + } + } + + // + // Position Filter ... + + // + int FilterSymbolBasedPositions( + string &symbols[], // Hold Symbols ... + XSCPositionHolder *&holders[] // Holder Class Instances ... + ) + { + // + int result = 0; + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions // + ); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + // Create a HashMap for Holding Positions ... + CHashMap symbolMap; + + // + // Loop Through Positions ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool hasIKey = symbolMap.ContainsKey(iPosition.symbol); + + // + // Empty Class Pointer ... + XSCPositionHolder *mHolder = NULL; + + // + // Add new to Map ... + if (!hasIKey) + { + // + mHolder = new XSCPositionHolder(); + if (symbolMap.TrySetValue(iPosition.symbol, mHolder)) + { + mHolder.AddOrUpdateItem(iPosition); + } + } + // + // Update Exists in Map ... + else + { + // + if (symbolMap.TryGetValue(iPosition.symbol, mHolder)) + { + mHolder.AddOrUpdateItem(iPosition); + } + } + } + + // + // Now we Have a Map which Filled Based on Separate Symbols and InDrawDown Positions ... + int mapCount = symbolMap.Count(); + if (!IsValidSize(mapCount)) + { + return result; + } + + // + result = symbolMap.CopyTo( + symbols, + holders // + ); + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + + // + // Signal Event Listeners ... + TOnSignal mOnSignalEventHandlers[]; + + // + // Position Management ... + bool mAllowLong; // Allow Long Trades + bool mAllowShort; // Allow Short Trades + double mMinProfitPerTrade; // Min Profit Per Trade based On Volume Factor (Hedge) + double mMinProfitPerVolumeFactor; // Min Volume Factor for Calculating Profit (Hedge) + double mStaticVolume; // Static Volume for Positions + + // + // Event Handlers ... + TOnStopLoss mOnStopLossTriggered; + TOnTakeProfit mOnTakeProfitTriggered; + TOnDealsChanged mOnDealsChangedHandler; + TOnOrdersChanged mOnOrdersChangedHandler; + TOnPositionsChanged mOnPositionsChangedHandler; + TOnTradeStateChanged mOnTradeStateChangedHandler; +}; + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhelper.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhelper.class.mq5 new file mode 100644 index 0000000..966eb8d --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhelper.class.mq5 @@ -0,0 +1,148 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseHelper +// Description: provides all Base Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +// Definitions ... + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseHelper : public XSCBase +{ + // + // Public ... +public: + // + // Constructor ... + void XSCBaseHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) + { + // + mSymbol = symbol; + mPeriod = period; + } + + // + // Deconstructor ... + void ~XSCBaseHelper() + { + // + IndicatorRelease(mHandler); + } + + // + // Setter(s) / Getter(s) ... + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Retrieve Bars ... + int CountBars() + { + // + int result = + Bars( + mSymbol, + mPeriod + // + ); + + // + return result; + } + + // + // Retrieve Indicator Calculated Bars ... + int CountCalculatedBars() + { + return BarsCalculated(mHandler); + } + + // + // Generate Tag ... + virtual string GetTag() + { + // + string result = NULL; + + // + result = + // + GetToken() + + "[" + + GetSymbol() + "|" + + ToString(GetPeriod()) + + "]" + // + ; + + // + return result; + } + + // + // Functions ... + + // + // Protected ... +protected: + // + // Props ... + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Indicator Handler ... + int mHandler; + + // + // Private ... +private: + // +}; + +// +// Tools .... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhttp.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhttp.class.mq5 new file mode 100644 index 0000000..82adadb --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xhttp.class.mq5 @@ -0,0 +1,373 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCHttp +// Description: provides all HTTP requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Definitions ... + +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; + +// +// Imports ... + +// +// Includes ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// a Class for Manage Account ... +class XSCHttp : public XSCBase +{ + // + // Public ... +public: + // + // Constructor ... + void XSCHttp() + { + XSCHttp("", 10000); + } + void XSCHttp( + string path, // Base Folder to Store Data + int timeout // base timeout for Requests + ) + { + // + Path(path); + Timeout(timeout); + } + + // + // Deconstructor ... + void ~XSCHttp() + { + } + + // + // Properties Getter(s) / Setter(s) ... + + // + // Path ... + void Path(string value) + { + // + mPath = value; + + // + if (!IsValid(mPath)) + { + mPath = GetTag(); + } + } + + string Path() + { + return mPath; + } + + // + // Timeout ... + void Timeout(int value) + { + mTimeout = value; + } + + // + int Timeout() + { + return mTimeout; + } + + // + // Error ... + int Error() + { + return mError; + } + + // + // Response ... + string Response() + { + return mResponse; + } + + // + // Overrides ... + string GetTag() override + { + return GetSpecificToken(this); + } + + // + // Tools ... + + // + // Send Global Request ... + int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) + { + return result; + } + + // + // Reset State ... + ResetState(); + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders); + + // + if (result < 0) + { + mError = GetLastError(); + } + else + { + mResponse = CharArrayToString(response); + } + + // + return result; + } + + // + // Get Request ... + int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + return result; + } + + // + // Post Request ... + int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + return result; + } + + // + // Handle Download Specific URL Content to Specific Path and File Name ... + bool Download( + string url, // the URL address which going to download + string fileName // Specify Destination file name to Store Response + ) + { + // + bool result = false; + + // + string filePath = GetFilePath(fileName); + string cookie = NULL; + string referer = NULL; + int timeout = Timeout(); + + // + char payload[]; + string headers; + char response[]; + string responseHeaders; + + // + // Send Request ... + int requestResult = GetRequest( + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + // Define File Handler ... + int mFileHandler = FileOpen( + filePath, + FILE_WRITE | FILE_BIN); + if (mFileHandler == INVALID_HANDLE) + { + // + mError = GetLastError(); + return result; + } + + // + // Write Response to File ... + uint writed = FileWriteArray( + mFileHandler, + response, + 0, + ArraySize(response)); + FileFlush(mFileHandler); + FileClose(mFileHandler); + + // + result = writed > 0; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Destintion Folder Path ... + string mPath; + + // + // WEB Request Timeout Value ... + int mTimeout; + + // + // WEB Request's Response ... + string mResponse; + + // + // Error Value ... + int mError; + + // + // Private ... +private: + // + // Reset Errors State ... + void ResetState() + { + // + // Reset Errors ... + mError = -1; + mResponse = ""; + ResetLastError(); + } + + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } +}; + +// +// Tools ... + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xmd5.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xmd5.class.mq5 new file mode 100644 index 0000000..3311aa5 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xmd5.class.mq5 @@ -0,0 +1,441 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCMD5 +// Description: Provides MD5 Hashing Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +static uchar _md5_PADDING[64] = + { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +// +#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define _md5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define _md5_I(x, y, z) ((y) ^ ((x) | (~z))) +#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +// +#define _md5_FF(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_GG(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_HH(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_II(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_INIT_STATE_0 0x67452301 +#define _md5_INIT_STATE_1 0xefcdab89 +#define _md5_INIT_STATE_2 0x98badcfe +#define _md5_INIT_STATE_3 0x10325476 + +// +#define _md5_S11 7 +#define _md5_S12 12 +#define _md5_S13 17 +#define _md5_S14 22 + +// +#define _md5_S21 5 +#define _md5_S22 9 +#define _md5_S23 14 +#define _md5_S24 20 + +// +#define _md5_S31 4 +#define _md5_S32 11 +#define _md5_S33 16 +#define _md5_S34 23 + +// +#define _md5_S41 6 +#define _md5_S42 10 +#define _md5_S43 15 +#define _md5_S44 21 + +// +// END Definitions ... +// + +// +// XCMD5 a library for Hashing ... +class XSCMD5 +{ + // + // Public Provides ... +public: + // + // Protected Provides ... + + // + // Constructor ... + XSCMD5(void) {} + + // + // Deconstructor ... + ~XSCMD5(void) {} + + // + // Hash Specified Char Array ... + string Hash( + uchar &mSource[], // Specify Char Array to Hash + int mLength = 0 // Specify Length of Char Array which required to hash + ) + { + // + string result = ""; + + // + int sourceCount = ArraySize(mSource); + + // + // Validate Args ... + if ( + sourceCount <= 0 || + (sourceCount > 0 && mLength > sourceCount)) + { + return result; + } + + // + // Normalize Args ... + if (mLength == 0) + { + mLength = sourceCount; + } + + // + // Init MD5 ... + MD5Init(); + + // + // Update Buffer ... + MD5Update(mSource, mLength); + + // + // Calculate Result ... + result = MD5Final(); + + // + return result; + } + + // + // Hash Specified String ... + string Hash( + string mSource // Specified String + ) + { + // + string result = ""; + + // + // Converts String to Char Array ... + uchar bytes[]; + StringToCharArray( + mSource, + bytes, + 0, + StringLen(mSource)); + + // + result = Hash( + bytes, + ArraySize(bytes)); + + // + return result; + } + +protected: + // + // Private Provides ... +private: + // + uint m_lMD5[4]; + uint m_nCount[2]; + uchar m_lpszBuffer[64]; + + // + // Convert Byte to DWord ... + void ByteToDWord(int &out[], uint &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24; + } + } + + // + // Convert DWord to Byte ... + void DWordToByte(uchar &out[], int &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + // + out[j] = (uchar)(in[i] & 0xff); + out[j + 1] = (uchar)((in[i] >> 8) & 0xff); + out[j + 2] = (uchar)((in[i] >> 16) & 0xff); + out[j + 3] = (uchar)((in[i] >> 24) & 0xff); + } + } + + // + // Init MD5 Array ... + void MD5Init() + { + // + ArrayInitialize(m_lpszBuffer, 64); + + // + m_nCount[0] = m_nCount[1] = 0; + m_lMD5[0] = _md5_INIT_STATE_0; + m_lMD5[1] = _md5_INIT_STATE_1; + m_lMD5[2] = _md5_INIT_STATE_2; + m_lMD5[3] = _md5_INIT_STATE_3; + } + + // + // Update MD5 ... + void MD5Update(uchar &inBuf[], uint inLen) + { + // + int i, ii; + int mdi; + + // + uint in[16]; + int i0 = 0; + + // + mdi = (int)((m_nCount[0] >> 3) & 0x3F); + + // + if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0]) + { + m_nCount[1]++; + } + + // + m_nCount[0] += ((uint)inLen << 3); + m_nCount[1] += ((uint)inLen >> 29); + + // + while ((inLen--) > 0) + { + // + m_lpszBuffer[mdi++] = inBuf[i0++]; + if (mdi == 0x40) + { + // + for (i = 0, ii = 0; i < 16; i++, ii += 4) + { + in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]); + } + + // + Transform(m_lMD5, in); + + // + mdi = 0; + } + } + } + + // + // Finalize an MD5 Expression ... + string MD5Final() + { + // + uchar bits[8]; + int nIndex; + uint nPadLen; + const int nMD5Size = 16; + uchar lpszMD5[16]; + string temp; + string out = ""; + int i; + + // + DWordToByte(bits, m_nCount, 8); + nIndex = (int)((m_nCount[0] >> 3) & 0x3f); + nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); + MD5Update(_md5_PADDING, nPadLen); + MD5Update(bits, 8); + DWordToByte(lpszMD5, m_lMD5, nMD5Size); + + // + for (i = 0; i < nMD5Size; i++) + { + // + if (lpszMD5[i] == 0) + { + temp = "00"; + } + else if (lpszMD5[i] <= 15) + { + temp = StringFormat("0%x", lpszMD5[i]); + } + else + { + temp = StringFormat("%x", lpszMD5[i]); + } + + // + out += temp; + } + + // + lpszMD5[0] = '\0'; + + // + return (out); + } + + // + // Transform Buffers ... + void Transform(uint &buf[], uint &in[]) + { + // + uint a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + // + _md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478); + _md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756); + _md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB); + _md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE); + _md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF); + _md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A); + _md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613); + _md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501); + _md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8); + _md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF); + _md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1); + _md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE); + _md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122); + _md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193); + _md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E); + _md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821); + + // + _md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562); + _md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340); + _md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51); + _md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA); + _md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D); + _md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453); + _md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681); + _md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8); + _md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6); + _md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6); + _md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87); + _md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED); + _md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905); + _md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8); + _md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9); + _md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A); + + // + _md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942); + _md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681); + _md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122); + _md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C); + _md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44); + _md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9); + _md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60); + _md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70); + _md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6); + _md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA); + _md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085); + _md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05); + _md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039); + _md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5); + _md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8); + _md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665); + + // + _md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244); + _md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97); + _md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7); + _md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039); + _md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3); + _md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92); + _md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D); + _md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1); + _md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F); + _md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0); + _md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314); + _md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1); + _md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82); + _md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235); + _md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB); + _md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391); + + // + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; + } +}; diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xprovider.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xprovider.class.mq5 new file mode 100644 index 0000000..753864d --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xprovider.class.mq5 @@ -0,0 +1,267 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseProvider +// Description: provides all Base Provider +// requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.xtrade.lib.mq5" + +// +// Definitions ... + +// +// Base Provider Inputs ... +class XSCBaseProviderInpts : public XSCBase +{ + // + // Public ... +public: + // + // Validate Input ... + virtual bool IsValid(); + + // + // Cleanup ... + virtual void Clean(); + + // + // Default ... + virtual void Default(); + + // + // Max ... + virtual int Max(); +}; + +// +// Base Market Conditions Class ... +class XSCBaseProviderMarketConditions : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + string symbol; // Symbol + ENUM_TIMEFRAMES period; // Period + datetime time; // Time + + // + XOHCL bars[]; // Number of Bars ... + + // + // Buffers ... + + // + // Conditions ... + + // + // Generate Score ... + virtual void GenerateScore( + double &bullishScore, // Bullish Score + double &bearishScore, // Bearish Score + double multiplier = 1 // Score Multiplier + ); + + // + // Generate Summary ... + virtual string GenerateSummary( + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ); +}; + +// +// Class ... + +// +// Base Provider Class ... +class XSCBaseProvider : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + XSCBaseProvider( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + double staticVolume // Static Volume for Positions + ) + { + // + // Initialize Cycle ... + mCycle.Init( + symbol, + period, + X_MARKET_CYCLE_SHORT, + X_PERIOD_MANUALLY, + period, + "HOST Period" + // + ); + + // + mStaticVolume = staticVolume; + } + + // + // Deconstructor ... + ~XSCBaseProvider() + { + DeInit(); + } + + // + // Properties Gettr(s) / Setter(s) ... + + // + // Inheritance ... + + // + // Init all Requirements ... + virtual bool Init(XSCBaseProviderInpts &inputs); + + // + // Get Inputs ... + virtual void GetInputs(XSCBaseProviderInpts &inputs); + + // + // Set Inputs and Reinitial ... + virtual bool setInputs(XSCBaseProviderInpts &inputs); + + // + // DeInit all Requirements ... + virtual void DeInit(); + + // + virtual void GetMarketConditions( + XSCBaseProviderMarketConditions &conditions, // Market Conditions Result + int barIndex = 0 // Specified Bar Index + ); + + // + // Check Market For Signal ... + virtual bool HasSignal( + int barIndex, + XSignal &signal, // Hold's Signal if Exists ... + XSCBaseProviderMarketConditions &conditions // Hold's Market Conditions ... + ); + + // + // Functions ... + + // + string GetSymbol() + { + return mCycle.symbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return mCycle.hostPeriod; + } + + // + double GetStaticVolume() + { + return mStaticVolume; + } + + // + // Count Bars ... + int CountBars() + { + // + return mCycle + .CountBars(); + } + + // + // Check New Bar ... + bool IsNewBar() + { + // + return mCycle + .IsNewBar(); + } + + // + // Protected ... +protected: + // + // Props ... + + // + double mStaticVolume; // Static Volume for Positions + + // + XMarketCycle mCycle; + + // + bool mWaitsUntilNewBar; + + // + // Can Ignore Process ... + bool CanIgnoreProcess() + { + // + bool result = false; + + // + result = + // + IsRunningOnTestMode() + ? !IsNewBar() + : !IsNewBar() && mWaitsUntilNewBar + // + ; + + // + return result; + } + + // + // Toggle Waititng Until New Candle ... + void ToggleWaitingUntilNewBar() + { + mWaitsUntilNewBar = !mWaitsUntilNewBar; + } + + // + // Private ... +private: + // + // Props ... + + // + // Tools ... +}; + +// +// Tools ... diff --git a/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xtrade.class.mq5 b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xtrade.class.mq5 new file mode 100644 index 0000000..d407060 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Classes/x-saherelm.xtrade.class.mq5 @@ -0,0 +1,3692 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCTrade +// Description: provides all Trade requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.xtrade.lib.mq5" +#include "../Classes/x-saherelm.xaccount.class.mq5" + +// +// Definitions ... + +// +// Overrides ... + +// +// XCTrade Base Class ... +class XSCTradeBase : public CTrade +{ +public: + // + // Modify Specific Position, by Specific Comment ... + bool PositionModify( + const string symbol, // Symbol + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!SelectPosition(symbol)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + bool PositionModify( + const ulong ticket, // Position Ticket + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.position = ticket; + m_request.symbol = PositionGetString(POSITION_SYMBOL); + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + + // + // Close Specific Position, by Specific Comment ... + bool PositionClose( + const string symbol, // Symbol + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + bool partial_close = false; + int retry_count = 10; + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + do + { + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specify Comment ... + m_request.comment = comment; + + // + // check volume + double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + if (m_request.volume > max_volume) + { + // + m_request.volume = max_volume; + partial_close = true; + } + else + { + partial_close = false; + } + + // + // hedging? just send order + if (IsHedging()) + { + return (OrderSend(m_request, m_result)); + } + + // + // order send + if (!OrderSend(m_request, m_result)) + { + // + if (--retry_count != 0) + { + continue; + } + + // + if (retcode == TRADE_RETCODE_DONE_PARTIAL) + { + m_result.retcode = retcode; + } + + // + return (false); + } + + // + //--- WARNING. If position volume exceeds the maximum volume allowed for deal, + //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, + //--- but partially. It is decreased by the maximum volume allowed for deal. + if (m_async_mode) + { + break; + } + + // + retcode = TRADE_RETCODE_DONE_PARTIAL; + if (partial_close) + { + Sleep(1000); + } + } while (partial_close); + + // + // succeed + return (true); + } + bool PositionClose( + const ulong ticket, // Position Ticket + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specify Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } + + // + // Partial Close Specific Position, by Specific Comment ... + bool PositionClosePartial( + const string symbol, // Symbol + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // hedging? just send order + return (OrderSend(m_request, m_result)); + } + bool PositionClosePartial( + const ulong ticket, // Position Ticket + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } +}; + +// +// Implementation ... + +// +// a Class For Manage Trades and Handle Trading Actions ... +class XSCTrade : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + void XSCTrade( + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + int manageInterval, // Manager Check Intervals Seconds + double maxAllowedSpread, // Max Allowed Spred for Opening Trades + int maxAllowedPositions, // Max Allowed Positions + double maxAllowedDrawdownFactor // Max Allowed Drawdown Factor + ) + { + // + // Setting Props ... + mSlippage = slippage; + mMagicNumber = magicNumber; + + // + mManageInterval = manageInterval; + + // + mMaxAllowedSpread = maxAllowedSpread; + mMaxAllowedPositions = maxAllowedPositions; + mMaxAllowedDrawdownFactor = maxAllowedDrawdownFactor; + + // + mAccount = new XSCAccount(); + + // + // Instance Base Trader Class ... + mTrader = new XSCTradeBase(); + + // + // Configuring Base Trader Class ... + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + // OnTrade Context ... + + // + mDaysForRead = 1; + mScanStarted = false; + + // + // Reset On Trade Counter ... + ResetOnTradeContext(); + + // + // Init On Trade Context ... + InitOnTradeContext(); + } + + // + // Deconstructor ... + ~XSCTrade() + { + // + // Remove Pointer ... + delete mTrader; + delete mAccount; + } + + // + // Props ... + + // + // Retrieve Slippage ... + int GetSlippage() + { + return mSlippage; + } + + // + // Retrieve Magic Number ... + ulong GetMagicNumber() + { + return mMagicNumber; + } + + // + int GetManageInterval() + { + return mManageInterval; + } + + // + double GetMaxAllowedSpread() + { + return mMaxAllowedSpread; + } + + // + int GetMaxAllowedPositions() + { + return mMaxAllowedPositions; + } + + // + double GetMaxAllowedDrawdownFactor() + { + return mMaxAllowedDrawdownFactor; + } + + // + // Add Event Listeners ... + + // + // Add New Deals Changed Event Handler ... + void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler) + { + // + Add( + handler, + mTradeStateChangedEventHandlers + // + ); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnDealsChangedEventHandler(TOnDealsChanged handler) + { + // + Add( + handler, + mDealsChangedEventHandlers + // + ); + } + + // + // Add New Orders Changed Event Handler ... + void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler) + { + // + Add( + handler, + mOrdersChangedEventHandlers + // + ); + } + + // + // Add New Positions Changed Event Handler ... + void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler) + { + // + Add( + handler, + mPositionsChangedEventHandlers + // + ); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnStopLossEventHandler(TOnStopLoss handler) + { + // + Add( + handler, + mStopLossEventHandlers + // + ); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnTakeProfitEventHandler(TOnTakeProfit handler) + { + // + Add( + handler, + mTakeProfitEventHandlers + // + ); + } + + // + // Functions ... + + // + // Handlers ... + + // + // Process On Trade Requirement ... + // this Only Used when we Have to Proccess OnTrade Event in EA(s) ... + void HandleOnTradeEvent( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + result.Clean(); + + // + if (mScanStarted) + { + // + ProcessOnTradeContext(result); + } + else + { + // + // Init Trade Context ... + InitOnTradeContext(); + + // + return; + } + + // + // Here we Can Check the Start ... + bool isValid = + // + result.IsValid() && + // + !result.hasNewDeal && + !result.hasNewOrder && + !result.hasNewPosition && + !result.hasNewHistoryOrder + // + ; + if (!isValid) + { + return; + } + + // + // State ... + + // + // Notfy Trade State Changed Event ... + NotifyTradeStateChangeEvent(result); + + // + // Deals ... + if (result.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + NotifyDealsChangeEvent(result.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + int dealsCount = GetDeals(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + NotifyTakeProfitEvent(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + NotifyStopLossEvent(lastDeal); + } + } + } + + // + // Orders ... + if (result.hasNewOrder || result.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + NotifyOrdersChangeEvent(result.newOrders + result.newHistoryOrders); + } + + // + // Positions ... + if (result.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + NotifyPositionsChangeEvent(result.newPositions); + } + } + + // + // This Must be Called Every time OnTrade Event Happening ... + // this Used for Implementing Custom Senarios ... + XOnTradeHandlerState HandleOnTrade() + { + // + // Handle OnTrade Event ... + XOnTradeHandlerState state; + HandleOnTradeEvent(state); + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return state; + } + + // + // State ... + + // + // Notfy Trade State Changed Event ... + NotifyTradeStateChangeEvent(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + NotifyDealsChangeEvent(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + NotifyTakeProfitEvent(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + NotifyStopLossEvent(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + NotifyOrdersChangeEvent(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + NotifyPositionsChangeEvent(state.newPositions); + } + + // + return state; + } + + // + // Trade Actions ... + + // + // Main ... + + // + // Policies ... + + // + // Check Acocunt Balance is Allow new Trades or not ... + bool CheckEquityForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedDrawdownFactor <= 0) + { + // + result = true; + return result; + } + + // + double equity = mAccount.GetEquity(); + double balance = mAccount.GetBalance(); + + // + double selectedBalance = MathMax(equity, balance) - MathMin(equity, balance); + + // + double maxAllowedBalanceDrawDown = GetMaxAllowedEquity(); + + // + result = equity > balance || + (equity <= balance && + selectedBalance <= maxAllowedBalanceDrawDown); + + // + return result; + } + + // + // Check Max Allowed Positions Policy for Trade ... + bool CheckPositionsForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedPositions <= 0) + { + // + result = true; + return result; + } + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (positionsCount <= 0) + { + // + result = true; + return result; + } + + // + result = positionsCount < mMaxAllowedPositions; + + // + return result; + } + + // + // Check Spread is Ok for Executing Specific Signal ... + bool CheckSpreadForSignalExecution(XSignal &mSignal) + { + // + bool result = false; + + // + bool isSpreadCheckEnable = mMaxAllowedSpread > 0; + if (!isSpreadCheckEnable) + { + result = true; + } + else + { + // + // Retrieve Signal Spread ... + double spread = mSignal.GetSpread(); + result = spread <= mMaxAllowedSpread; + } + + // + return result; + } + + // + // Check Account Policy ... + bool CheckAccountPolicy( + XSignal &mSignal, // For Executing Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &state // State Holder + ) + { + // + bool result = false; + + // + // Check Positions For Trade ... + result = CheckPositionsForTrade(); + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; + return result; + } + + // + // Check Equity For Trade ... + result = CheckEquityForTrade(); + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_NO_EQUITY; + return result; + } + + // + // Check Spread for Trade ... + result = CheckSpreadForSignalExecution(mSignal); + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_SPREAD; + return result; + } + + // + return result; + } + + // + // Manage ... + // this must be Call on OnTick for Manage + // Positions ... + // NOTE: Call this Before Checking IsNewBar ... + void Manage() + { + // // + // // All required Position Managements Actions implemented here ... + // datetime tmc = TimeCurrent(); + // bool canManage = !IsValid(mLastManageOn) + // ? true + // : mLastManageOn + mManageInterval >= tmc; + // if (!canManage) + // { + // return; + // } + + // // + // mLastManageOn = tmc; + + // + // - [] Partial Close; + // - [] Risk Free; + // - [] Trail Stop; + // - [] SLS; + // - [] TPS; + + // + // - [] Data Collector; + // - [] Profit Management; + + // + // TODO: Implement them ... + + // + // Implement Signal Collector Inside this Class + // and Manipulate Signals when SL/TP/Partial Close/Trail Stop/Profit/Close/ Modify and etc Happens ... + } + + // + // Execute a Signal ... + bool ExecuteSignal( + XSignal &mSignal, // Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Result + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL, // order expiration time + bool checkPolicies = true // Check Account Policies + ) + { + // + bool result = false; + state = X_SIGNAL_EXECUTION_UNKNOWN; + + // + double currentEntry = GetEntry( + mSignal.symbol, + mSignal.type + // + ); + bool isLong = IsLong(mSignal.type); + + // + // Select SL and TP ... + + // + double selectedSL = 0; + mSignal.RegularSL(selectedSL); + + // + double selectedTP = 0; + mSignal.RegularTP(selectedTP); + + // + if (!mSignal.IsValid()) + { + // + state = X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS; + return result; + } + + // + // Prepare Signal Comment ... + string mSComment = mSignal.GenerateComment(); + mSignal.comment += mSComment; + + // + // Handle Market Execution ... + if (mSignal.mode == X_ORDER_MODE_MARKET) + { + // + // Do Apply Policies here ... + bool hasPolicy = !checkPolicies + ? true + : CheckAccountPolicy(mSignal, state); + if (!hasPolicy) + { + result = false; + } + else + { + // + if (isLong) + { + // + result = Buy( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + selectedSL, + selectedTP, + mSignal.comment + // + ); + } + else + { + // + result = Sell( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + selectedSL, + selectedTP, + mSignal.comment + // + ); + } + } + } + // + // Handle Stop Execution ... + else if (mSignal.mode == X_ORDER_MODE_STOP) + { + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? mSignal.entry > currentEntry + : mSignal.entry < currentEntry; + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR; + return result; + } + + // + // Execute Order ... + if (isLong) + { + // + result = BuyStop( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + selectedSL, + selectedTP, + lifetime, + expiration, + mSignal.comment + // + ); + } + else + { + // + result = SellStop( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + selectedSL, + selectedTP, + lifetime, + expiration, + mSignal.comment + // + ); + } + } + // + // Handle Limit Execution ... + else if (mSignal.mode == X_ORDER_MODE_LIMIT) + { + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? mSignal.entry < currentEntry + : mSignal.entry > currentEntry; + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR; + return result; + } + + // + // Execute Order ... + if (isLong) + { + // + result = BuyLimit( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + selectedSL, + selectedTP, + lifetime, + expiration, + mSignal.comment + // + ); + } + else + { + // + result = SellLimit( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + selectedSL, + selectedTP, + lifetime, + expiration, + mSignal.comment + // + ); + } + } + + // + // Handle Ticket ... + if (result) + { + // + state = X_SIGNAL_EXECUTION_SUCCEED; + + // + ulong ticket; + if (mSignal.mode == X_ORDER_MODE_MARKET) + { + ticket = GetLastOpenPositionTicket(); + } + else + { + ticket = GetLastPlacedOrderTicket(); + } + + // + mSignal.positionId = ticket; + + // + // Handle Store XPositionInfo ... + if (mSignal.mode == X_ORDER_MODE_MARKET) + { + // + // TODO: Implement this ... + } + + // + // Handle Executing Support Signals ... + int supportsCount = ArraySize(mSignal.supports); + if (supportsCount > 0) + { + // + int executed = 0; + for (int i = 0; i < supportsCount; i++) + { + // + XSignal iSupport = mSignal.supports[i]; + + // + int supIndex = i + 1; + string iComment = GenerateSupportTag(ticket); + + // + bool isExecuted = ExecuteSignal( + iSupport, + state, + lifetime, + expiration + // + ); + if (isExecuted) + { + executed++; + } + } + + // + result = executed == supportsCount; + } + } + + // + return result; + } + + // + // Execute a Collection Of Signals ... + int ExecuteSignals( + XSignal &signals[], // Collection of Signal for Execution + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL, // order expiration time + bool checkPolicies = true // Check Account Policies + ) + { + // + int result = 0; + + // + Clean(states); + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + ArrayResize(states, signalsCount); + ArrayInitialize(states, X_SIGNAL_EXECUTION_UNKNOWN); + for (int i = 0; i < signalsCount; i++) + { + // + bool isExecuted = ExecuteSignal( + signals[i], + states[i], + lifetime, + expiration + // + ); + + // + if (isExecuted) + { + result++; + } + } + + // + return result; + } + + // + int ExecuteSpecifiedSignals( + XSignal &signals[], // Collection of Signal for Execution + XSignal ¬Executeds[], // Not Executed Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL, // order expiration time + bool checkPolicies = true // Check Account Policies + ) + { + // + int result = 0; + + // + Clean(states); + Clean(notExecuteds); + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + ArrayResize(states, signalsCount); + ArrayInitialize(states, X_SIGNAL_EXECUTION_UNKNOWN); + for (int i = 0; i < signalsCount; i++) + { + // + bool isExecuted = ExecuteSignal( + signals[i], + states[i], + lifetime, + expiration + // + ); + + // + if (isExecuted) + { + result++; + } + else + { + // + AddRef( + signals[i], + notExecuteds // + ); + } + } + + // + return result; + } + + // + // Regular Trade Actions ... + + // + // Buy ... + + // + // Force Open a Buy/Long Position ... + bool Buy( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.Buy( + volume, + symbol, + price, + sl, + tp, + comment + // + ); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.BuyLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.BuyStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Sell ... + + // + // Force Open a Sell/Short Position ... + bool Sell( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.Sell( + volume, + symbol, + price, + sl, + tp, + comment + // + ); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.SellLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.SellStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Check a Position is Exists Open or not ... + bool IsOpen( + ulong ticket // Specified Position Ticket + ) + { + // + bool result = false; + + // + result = mPositionInfo + .SelectByTicket(ticket); + + // + return result; + } + + // + // Modify Position ... + bool Modify( + const ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0, // take profit + string comment = NULL // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + result = + IsOpen(ticket) && + (tp >= 0 || sl >= 0); + if (!result) + { + return result; + } + + // + // Use Position Comment when there isn't new One ... + if (!IsValid(comment) == 0) + { + // + // if there isn't provided Comment + // Use Position Comment for default ... + comment = "Modify " + GetPositionComment(ticket); + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment + // + ); + + // + return result; + } + + // + // Close Position By Ticket ... + bool Close( + ulong ticket, // Position Ticket + string comment = NULL // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + // Check Position Open ... + result = IsOpen(ticket); + if (!result) + { + return result; + } + + // + // Use Default Position Comment if it's Not Provided ... + if (!IsValid(comment)) + { + comment = "Close " + GetPositionComment(ticket); + } + + // + // Close Position By Specific Comment ... + result = mTrader.PositionClose( + ticket, + mSlippage, + comment + // + ); + + // + return result; + } + + // + // Close Specified Positions ... + int Close( + string comment = NULL, // Close Position By Specific Comment + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true // Get Only Self Open Positions + ) + { + // + int result = 0; + + // + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = Close( + iPosition.ticket, + comment + // + ); + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Close a Collection of Positions ... + int Close( + XPosition &positions[], // Collection of Positions + string comment // Close Comment + ) + { + // + int result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = Close( + iPosition.ticket, + comment + // + ); + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Close Partial By Ticket ... + bool ClosePartial( + ulong ticket, // Position Ticket + double volume, // Volume Size for Partial Closing + string comment = NULL // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + result = IsOpen(ticket); + if (!result) + { + return result; + } + + // + // Use Default Partial Close Comment ... + if (!IsValid(comment)) + { + // + comment += "PClose " + GetPositionComment(ticket); + } + + // + result = mTrader.PositionClosePartial( + ticket, + volume, + mSlippage, + comment + // + ); + + // + return result; + } + + // + // Cancel Specific Order ... + bool CancelOrder(ulong ticket) + { + return mTrader + .OrderDelete(ticket); + } + + // + // Cancel Specific Orders ... + int CancelOrders( + XOrder &orders[] // Specified Orders ... + ) + { + // + int result = 0; + + // + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + bool isDeleted = mTrader + .OrderDelete(iOrder.ticket); + if (isDeleted && !result) + { + result++; + } + } + + // + return result; + } + + // + // Extractors ... + + // + // Positions ... + + // + // Calculate Positions Profit ... + double Profit( + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true // Get Only Self Open Positions + ) + { + // + double result = 0; + + // + // Retrieve Positions ... + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic + // + ); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + result += positions[i].profit; + } + + // + return result; + } + + // + // Retrieve Specific Position by Index ... + bool GetPosition( + int index, // Specified Index + XPosition &result // Hold's Result + ) + { + // + return result + .ByIndex(index); + } + + // + // Retrieve Specific Position by Ticket ... + bool GetPosition( + ulong ticket, // Specified Ticket + XPosition &result // Hold's Result + ) + { + // + return result + .ByTicket(ticket); + } + + // + // Retrieve Positions ... + int GetPositions( + XPosition &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = PositionsTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XPosition iItem; + bool isLoaded = iItem.ByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Select In Profit Positions ... + int GetInProfitPositions( + XPosition &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + ENUM_X_POSITION_SELECT_METHODS method = NULL, // Selection Method + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic, + forceClean); + if (positionsCount <= 0) + { + return mResult; + } + + // + XPosition min; + XPosition max; + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + if (iPosition.profit <= 0) + { + continue; + } + + // + // Calculate Min and Max ... + + // + // Min ... + if (!min.IsValid() || min.profit <= 0 || min.profit > iPosition.profit) + { + min = iPosition; + } + + // + // Max ... + if (!max.IsValid() || max.profit <= 0 || max.profit < iPosition.profit) + { + max = iPosition; + } + + // + bool isSelectionMethodFilterPassed = + // + (method == NULL || + method == X_POSITION_SELECT_ALL) + ? true + : false; + // + ; + if (!isSelectionMethodFilterPassed) + { + continue; + } + + // + AddRef( + iPosition, + result + // + ); + } + + // + if (min.IsValid() && + (method == X_POSITION_SELECT_MIN || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + min, + result + // + ); + } + + // + if (max.IsValid() && + (method == X_POSITION_SELECT_MAX || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + max, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Select In Drawdown Positions ... + int GetInDrawdownPositions( + XPosition &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_POSITION_TYPE type = NULL, // Long (Buy) or Short (Sell) + ENUM_X_POSITION_SELECT_METHODS method = NULL, // Selection Method + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic, + forceClean); + if (positionsCount <= 0) + { + return mResult; + } + + // + XPosition min; + XPosition max; + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + if (iPosition.profit >= 0) + { + continue; + } + + // + // Calculate Min and Max ... + + // + // Min ... + if (!min.IsValid() || min.profit <= 0 || min.profit > iPosition.profit) + { + min = iPosition; + } + + // + // Max ... + if (!max.IsValid() || max.profit <= 0 || max.profit < iPosition.profit) + { + max = iPosition; + } + + // + bool isSelectionMethodFilterPassed = + // + (method == NULL || + method == X_POSITION_SELECT_ALL) + ? true + : false; + // + ; + if (!isSelectionMethodFilterPassed) + { + continue; + } + + // + AddRef( + iPosition, + result + // + ); + } + + // + if (min.IsValid() && + (method == X_POSITION_SELECT_MIN || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + min, + result + // + ); + } + + // + if (max.IsValid() && + (method == X_POSITION_SELECT_MAX || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + max, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Orders ... + + // + // Retrieve Specific Order by Index ... + bool GetOrder( + int index, // Specified Index + XOrder &result // Hold's Result + ) + { + // + return result + .ByIndex(index); + } + + // + // Retrieve Specific Positions Orders ... + int GetOrders( + ulong ticket, // Positions Ticket + XOrder &result[], // Hold's Result + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + // Select History by Specified Ticket ... + bool isHistorySelected = HistorySelectByPosition(ticket); + if (!isHistorySelected) + { + return mResult; + } + + // + int ordersCount = HistoryOrdersTotal(); + if (ordersCount <= 0) + { + return mResult; + } + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder; + bool isLoaded = iOrder.HistoryByIndex(i); + if (!isLoaded) + { + continue; + } + + // + bool isTicketFilterPassed = + // + iOrder.ticket = ticket + // + ; + if (!isTicketFilterPassed) + { + continue; + } + + // + AddRef( + iOrder, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Retrieve All Orders ... + int GetOrders( + XOrder &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_ORDER_TYPE type = NULL, // Long (Buy) or Short (Sell) + ENUM_ORDER_STATE state = NULL, // Order State + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = OrdersTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XOrder iItem; + bool isLoaded = iItem.ByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + state, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Retrieve Historical Orders ... + int GetOrders( + XOrder &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_ORDER_TYPE type = NULL, // Long (Buy) or Short (Sell) + ENUM_ORDER_STATE state = NULL, // Order State + datetime startDate = NULL, // Specify Start Date + datetime endDate = NULL, // Specify End Date + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + endDate = NormalizeTime(endDate); + + // + if (!IsValid(startDate)) + { + startDate = endDate - PeriodSeconds(PERIOD_D1); + } + + // + bool isHistorySelected = HistorySelect( + startDate, + endDate); + if (!isHistorySelected) + { + return mResult; + } + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = OrdersTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XOrder iItem; + bool isLoaded = iItem.HistoryByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + state, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Deals ... + + // + // Retrieve Specific Deal by Index ... + bool GetDeal( + int index, // Specified Index + XDeal &result // Hold's Result + ) + { + // + return result + .ByIndex(index); + } + + // + // Retrieve Specified Deal's History ... + int GetDealsHistory( + XDeal &deal, // Specified Deal + XOrder &history[], // Deals History + bool forceClean = true // Clean Result Array + ) + { + // + int result = 0; + + // + if (!deal.IsValid()) + { + return result; + } + + // + result = GetOrders( + deal.positionId, + history, + forceClean); + + // + return result; + } + + // + // Retrieve All Deals ... + int GetDeals( + XDeal &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_DEAL_TYPE type = NULL, // Deal Type + ENUM_DEAL_ENTRY entry = NULL, // Deal Entry + ENUM_DEAL_REASON reason = NULL, // Deal Reason + datetime startDate = NULL, // Specify Start Date + datetime endDate = NULL, // Specify End Date + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + endDate = NormalizeTime(endDate); + + // + if (!IsValid(startDate)) + { + startDate = endDate - PeriodSeconds(PERIOD_D1); + } + + // + bool isHistorySelected = HistorySelect( + startDate, + endDate); + if (!isHistorySelected) + { + return mResult; + } + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = HistoryDealsTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XDeal iItem; + bool isLoaded = iItem.ByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + entry, + reason, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // XPosition Pack ... + + // + // Extract specific Positions Pack ... + // in this senario there is no need to Position exists itself ... + bool GetPositionPack( + ulong ticket, // Specified Positions Ticket + string symbol, // Specified Position Symbol + ENUM_TIMEFRAMES period, // Specified Position Period + XPositionPack &pack // Hold Result + ) + { + // + bool result = false; + + // + pack.Clean(); + + // + XPosition position; + bool hasPosition = GetPosition( + ticket, + position + // + ); + if (hasPosition) + { + pack.position = position; + } + + // + XOrder supportOrders[]; + XPosition supportPositions[]; + + // + XOrder orders[]; + GetOrders( + orders, + symbol, // Specified Symbol + NULL, // All Providers + period, // Specified Period + NULL, // All Types + ORDER_STATE_PLACED, // Just UnTriggered Orders + true // Filter by Magic + ); + int ordersCount = ArraySize(orders); + + // + // Select Orders ... + if (ordersCount > 0) + { + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + // Retrieve Order Supported Ticket ... + ulong parentTicket = ExtractSupportedTicket(iOrder.comment); + if (NotEmpty(parentTicket) && parentTicket == ticket) + { + // + AddRef( + iOrder, + supportOrders + // + ); + } + } + } + + // + int supportOrdersCount = ArraySize(supportOrders); + if (supportOrdersCount > 0) + { + // + pack.supportOrdersCount = supportOrdersCount; + + // + Copy( + supportOrders, + pack.supportOrders); + } + + // + XPosition positions[]; + GetPositions( + positions, + symbol, // Specified Symbol ... + NULL, // All Providers ... + period // Specified Period ... + ); + int positionsCount = ArraySize(positions); + + // + // Select Positions ... + if (positionsCount > 0) + { + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + ulong parentTicket = ExtractSupportedTicket(iPosition.comment); + if (NotEmpty(parentTicket) && parentTicket == ticket) + { + // + AddRef( + iPosition, + supportPositions + // + ); + } + } + } + + // + int supportPositionsCount = ArraySize(supportPositions); + if (supportPositionsCount > 0) + { + // + pack.supportPositionsCount = supportPositionsCount; + + // + Copy( + supportPositions, + pack.supportPositions); + } + + // + result = pack.IsValid(); + + // + return result; + } + + // + // Close Position Pack ... + bool ClosePositionPack( + XPositionPack &pack, // Specified Position Pack + string comment, // Specified Close Comment + bool inProfit = false, // if it's true only close Pack if in profit + double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... + double minProfitPerVolumeFactor = 0 // Min Volume Factor ... + ) + { + // + bool result = false; + + // + ulong ticket = pack.ticket; + + // + XPosition positions[]; + + // + XPosition pPosition; + result = GetPosition( + ticket, + pPosition // + ); + if (result) + { + // + AddRef( + pPosition, + positions // + ); + } + + // + if (pack.supportPositionsCount > 0) + { + // + for (int i = 0; i < pack.supportPositionsCount; i++) + { + // + XPosition iPosition = pack.supportPositions[i]; + + // + AddRef( + iPosition, + positions // + ); + } + } + + // + // Force Close ... + if (!inProfit) + { + // + int closed = Close( + positions, + comment // + ); + + // + int cancelled = 0; + if (pack.supportOrdersCount > 0) + { + cancelled = CancelOrders(pack.supportOrders); + } + + // + result = (closed + cancelled) == (pack.supportPositionsCount + pack.supportOrdersCount + 1); + } + else + { + // + bool canHedge = SpecifiedIsPositionsReadyForHedge( + positions, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + if (canHedge) + { + // + int closed = Close( + positions, + comment // + ); + + // + int cancelled = 0; + if (pack.supportOrdersCount > 0) + { + cancelled = CancelOrders(pack.supportOrders); + } + + // + result = (closed + cancelled) == (pack.supportPositionsCount + pack.supportOrdersCount + 1); + } + else + { + result = false; + } + } + + // + return result; + } + bool ClosePositionPack( + ulong ticket, // Specified Position Pack + string symbol, // Specified Position Symbol + ENUM_TIMEFRAMES period, // Specified Position Period + string comment, // Specified Close Comment + bool inProfit = false, // if it's true only close Pack if in profit + double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... + double minProfitPerVolumeFactor = 0 // Min Volume Factor ... + ) + { + // + bool result = false; + + // + XPositionPack pack; + result = GetPositionPack( + ticket, + symbol, + period, + pack // + ); + if (!result) + { + return result; + } + + // + result = ClosePositionPack( + pack, + comment, + inProfit, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + + // + return result; + } + + // + // Close Positions Pack ... + int ClosePositionsPack( + XPosition &positions[], // Positions ... + string comment, // Specified Close Comment + bool inProfit = false, // if it's true only close Pack if in profit + double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... + double minProfitPerVolumeFactor = 0 // Min Volume Factor ... + ) + { + // + int result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = ClosePositionPack( + iPosition.ticket, + iPosition.symbol, + iPosition.period, + comment, + inProfit, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + + // + // Event Listener Notifiers ... + + // + // State ... + void NotifyTradeStateChangeEvent(const XOnTradeHandlerState &state) + { + // + int count = ArraySize(mTradeStateChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTradeStateChanged iHandler = mTradeStateChangedEventHandlers[i]; + iHandler(state); + } + } + + // + // Deals ... + void NotifyDealsChangeEvent(int changes) + { + // + int count = ArraySize(mDealsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnDealsChanged iHandler = mDealsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // Orders ... + void NotifyOrdersChangeEvent(int changes) + { + // + int count = ArraySize(mOrdersChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnOrdersChanged iHandler = mOrdersChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // Positions ... + void NotifyPositionsChangeEvent(int changes) + { + // + int count = ArraySize(mPositionsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnPositionsChanged iHandler = mPositionsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // StopLoss ... + void NotifyStopLossEvent(const XDeal &deal) + { + // + int count = ArraySize(mStopLossEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnStopLoss iHandler = mStopLossEventHandlers[i]; + iHandler(deal); + } + } + + // + // Take Profit ... + void NotifyTakeProfitEvent(const XDeal &deal) + { + // + int count = ArraySize(mTakeProfitEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTakeProfit iHandler = mTakeProfitEventHandlers[i]; + iHandler(deal); + } + } + + // + // Tools ... + + // + // Retrieve Specified Position Comment ... + string GetPositionComment(ulong ticket) + { + // + string result = NULL; + + // + if (!IsOpen(ticket)) + { + return result; + } + + // + XPosition position; + bool isLoaded = position.ByTicket(ticket); + if (!isLoaded) + { + return result; + } + + // + result = position.comment; + + // + return result; + } + + // + // Retrieve Last Open Position Ticket ... + ulong GetLastOpenPositionTicket() + { + // + ulong result = 0; + + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + result = PositionGetTicket(PositionsTotal() - 1); + + // + return result; + } + + // + // Retrieve Last Placed Order Ticket ... + ulong GetLastPlacedOrderTicket() + { + // + ulong result = 0; + + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + if (mOrderInfo.SelectByIndex(ordersCount - 1)) + { + result = mOrderInfo.Ticket(); + } + + // + return result; + } + + // + // Extract Specific Deals Position's Pack ... + // this used when a Position SL or TP triggered and we want to close + // all it's Supported Packs ... + bool GetDealPack( + XDeal &deal, + XPositionPack &pack // + ) + { + // + bool result = false; + + // + ulong ticket = deal.positionId; + ENUM_TIMEFRAMES dealPeriod = GetDealPeriod(deal); + string dealSymbol = deal.symbol; + + // + // So We Have to Get Positions Pack ... + result = GetPositionPack( + ticket, + dealSymbol, + dealPeriod, + pack + // + ); + + // + return result; + } + + // + ENUM_TIMEFRAMES GetDealPeriod(XDeal &deal) + { + // + ENUM_TIMEFRAMES result = NULL; + + // + XOrder orders[]; + int ordersCount = GetDealsHistory( + deal, + orders); + if (!ordersCount) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + if (IsValid(iOrder.comment)) + { + // + ENUM_TIMEFRAMES iPeriod = ExtractPeriod(iOrder.comment); + if (IsValid(iPeriod)) + { + result = iPeriod; + break; + } + } + } + + // + return result; + } + + // + double GetMaxAllowedEquity() + { + // + double equity = mAccount.GetEquity(); + double balance = mAccount.GetBalance(); + + // + double balanceForFactor = MathAbs(equity - balance); + if (balanceForFactor <= 0) + { + balanceForFactor = balance; + } + else + { + balanceForFactor = equity; + } + + // + double result = balanceForFactor * mMaxAllowedDrawdownFactor; + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + + // + int mSlippage; // Slippage ... + ulong mMagicNumber; // Magic Number (Unique Identifier) ... + + // + datetime mLastManageOn; // Last Manager Check + int mManageInterval; // Manager Check Intervals Seconds + + // + double mMaxAllowedSpread; // Max Allowed Spred for Opening Trades + int mMaxAllowedPositions; // Max Allowed Same Positions + double mMaxAllowedDrawdownFactor; // Max Allowed Drawdown Factor + + // + XSCAccount *mAccount; // Account Info Provider + XSCTradeBase *mTrader; // Base CTrade Manipulated Instance ... + + // + CDealInfo mDealInfo; // Deals Info ... + COrderInfo mOrderInfo; // Order Info ... + CPositionInfo mPositionInfo; // Positions Info + CHistoryOrderInfo mHistoryOrderInfo; // History Orders Info ... + + // + // Position Info Collector ... + + // + // Tools ... + + // + // OnTrade Event Handlers Section ... + + // + // Props ... + + // + int mDaysForRead; // Reading Dates for Trade History Checker ... + datetime mEndDate; // End Date for Trade history Checking ... + datetime mStartDate; // Start Date for Trade history Checking ... ... + int mOrdersCount; // Number of Active orders ... + int mPositionsCount; // Number of Open positions ... + int mDealsCount; // Number of Deals in the Trade History Checking ... + int mHistoryOrdersCount; // Number of Orders in the Trade History Checking ... + bool mScanStarted; // a Flag of counter relevance ... + + // + // Event Listeners ... + + // + // Deals Changed Event Handlers ... + TOnDealsChanged mDealsChangedEventHandlers[]; + + // + // Orders Changed Event Handlers ... + TOnOrdersChanged mOrdersChangedEventHandlers[]; + + // + // Positions Changed Event Handlers ... + TOnPositionsChanged mPositionsChangedEventHandlers[]; + + // + // Trade State Changed Event Handlers ... + TOnTradeStateChanged mTradeStateChangedEventHandlers[]; + + // + // TPSL ... + TOnStopLoss mStopLossEventHandlers[]; + TOnTakeProfit mTakeProfitEventHandlers[]; + + // + // Reset On Trade Scanner Context ... + void ResetOnTradeContext() + { + // + mEndDate = TimeCurrent(); + mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + } + + // + // Initial Context Of Trade Scanner ... + void InitOnTradeContext() + { + // + ResetLastError(); + + // + mOrdersCount = OrdersTotal(); + mPositionsCount = PositionsTotal(); + + // + // load history ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current value ... + mDealsCount = HistoryDealsTotal(); + mHistoryOrdersCount = HistoryOrdersTotal(); + + // + mScanStarted = true; + } + + // + // Check Statrt Date In Trade History ... + void CheckStartDateInTradeHistory() + { + // + // initial interval, if we were to start working right now .. + datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + + // + // make sure that the start limit of the trade history has not gone + // more than 1 day over the intended date ... + if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) + { + // + // correct the start date of history to be loaded in the cache ... + mStartDate = currStart; + + // + // now reload the trade history for the updated interval ... + HistorySelect(mStartDate, mEndDate); + + // + // correct the deal and order counters in history for further comparison + mHistoryOrdersCount = HistoryOrdersTotal(); + mDealsCount = HistoryDealsTotal(); + } + } + + // + // Process On Trade Context ... + void ProcessOnTradeContext( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + mEndDate = TimeCurrent(); + + // + ResetLastError(); + + // + // download trading history from the specified interval to the program cache ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current values ... + int currOrders = OrdersTotal(); + int currPositions = PositionsTotal(); + int currDeals = HistoryDealsTotal(); + int currHistoryOrders = HistoryOrdersTotal(); + + // + // Orders ... + // check if the number of active orders has been changed ... + if (currOrders != mOrdersCount) + { + // + // number of active orders has been changed ... + result.hasNewOrder = true; + result.newOrders = currOrders - mOrdersCount; + + // + // update the value ... + mOrdersCount = currOrders; + } + + // + // Positions ... + // changes in the number of open positions ... + if (currPositions != mPositionsCount) + { + // + // number of open positions has been changed ... + result.hasNewPosition = true; + result.newPositions = currPositions - mPositionsCount; + + // + // update the value ... + mPositionsCount = currPositions; + } + + // + // Deals ... + // changes in the number of deals in the trade history cache ... + if (currDeals != mDealsCount) + { + // + // number of deals in the trade history cache has been changed ... + result.hasNewDeal = true; + result.newDeals = currDeals - mDealsCount; + + // + // update the value ... + mDealsCount = currDeals; + } + + // + // History Orders ... + // changes in the number of history orders in the trade history cache ... + if (currHistoryOrders != mHistoryOrdersCount) + { + // + // number of history orders in the trade history cache has been changed ... + result.hasNewHistoryOrder = true; + result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; + + // + // update the value ... + mHistoryOrdersCount = currHistoryOrders; + } + + // + // checking if it is necessary to change the limits of the trade history to be requested in cache ... + CheckStartDateInTradeHistory(); + } +}; + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Experts/x-test.x121ea.mq5 b/MQLTestWorkspace/BKPS/14030309/Experts/x-test.x121ea.mq5 new file mode 100644 index 0000000..5b970d5 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Experts/x-test.x121ea.mq5 @@ -0,0 +1,1011 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center X121EA MQL5 Expert Advisor +// ------------------------------------------------- +// Name: X121EA +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121EA" +#property strict + +// +#define ShortName "X121EA" + +// +#include "../Classes/x-saherelm.x121.xea.class.mq5" + +// +// "EURUSDb,USDCHFb,USDJPYb,XAUUSDb" +// "EURUSDb,USDCHFb,USDJPYb,GBPUSDb,XAUUSDb,AUDUSDb,USDCADb,NZDUSDb" + +// +// Inputs ... +input long x121EAMagicNumber = 78692110; // Magic Number +input int x121EASlippage = 10; // Slippgae +input string x121EASymbols = "EURUSDb"; // Symbols +// +input bool x121EAAllowLong = true; // Allow Long Trades +input bool x121EAAllowShort = true; // Allow Short Trades +input int x121EAManageInterval = 0; // Manager Check Intervals Seconds +input int x121EAMaxAllowedPositions = 5; // Max Allowed Positions +input double x121EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades +input double x121EAMinProfitPerTrade = 0; // Min Profit Per Trade based On Volume Factor (Hedge) +input double x121EAMinProfitPerVolumeFactor = 0.0; // Min Volume Factor for Calculating Profit (Hedge) +input double x121EAMaxAllowedDrawdownFactor = 0.002; // Max Allowed Drawdown Factor +// +input double x121EAVolume = 0.01; // Static Volume + +// +// Vars ... +string x121EASymbol; +ENUM_TIMEFRAMES x121EAPeriod; + +// +MqlTick x121EATick; + +// +// X121EA ... +XSCX121EA *mX121EA; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + if (x121EASymbol == NULL || StringLen(x121EASymbol) <= 0) + { + x121EASymbol = _Symbol; + } + + // + if (x121EAPeriod == NULL) + { + x121EAPeriod = _Period; + } + + // + // Validate Inputs ... + if (!X121EAValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initial EA ... + if (!InitialEA()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // TesterHideIndicators(true); + + // + mX121EA.Alert(ShortName + " Initialized Sccessfully ..."); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize X121EA Providers ... + mX121EA.Alert(ShortName + " Deinitialized ..."); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Reading Tick ... + if (!SymbolInfoTick(x121EASymbol, x121EATick)) + { + return; + } + + // + mX121EA.OnTick(); +} + +// +// Custom Functions ... + +// +// Validate Variables nd Inputs ... +bool X121EAValidateInputs() +{ + // + bool result = false; + + // + result = + // + x121EASlippage > 0 && + x121EAMagicNumber > 0 + // + ; + + // + return result; +} + +// +// Initialize Specific Providers ... +bool InitialEA() +{ + // + bool result = false; + + // + // Here We Have to Initial 4 instance of X5Provider ... + // - EURUSD/M5; + // - USDCHF/M5; + // - USDJPY/M5; + // - XAUUSD/M5; + + // + result = IsValid(x121EASymbols); + if (!result) + { + return result; + } + + // + string symbols[]; + int symbolsCount = SplitContent( + symbols, + x121EASymbols); + result = symbolsCount > 0; + if (!result) + { + return result; + } + + // + // Define Signallers ... + ENUM_X121_SIGNAL_PROVIDERS signallers[]; + // Add(X786, signallers); + Add(X121, signallers); + // Add(X121, signallers); + // Add(X128, signallers); + // Add(X92, signallers); + // Add(XTEST, signallers); + // GetAllX121SignalProviders(signallers); + + // + // Instantiate X121EA Class ... + mX121EA = new XSCX121EA( + x121EASlippage, // Slippgae + x121EAMagicNumber, // Magic Number + x121EAManageInterval, // Manager Check Intervals Seconds + x121EAMaxAllowedSpread, // Max Allowed Spred for Opening Trades + x121EAMaxAllowedPositions, // Max Allowed Positions + x121EAMaxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + x121EAVolume, // Static Volume for Positions + x121EAAllowLong, // Allow Long Trades + x121EAAllowShort, // Allow Short Trades + x121EAMinProfitPerTrade, // Min Profit Per Trade based On Volume Factor (Hedge) + x121EAMinProfitPerVolumeFactor // Min Volume Factor for Calculating Profit (Hedge) + ); + + // + mX121EA.SetAlertPrefix(ShortName); + + // + // Prepare Providers and Add them into mX121EA class ... + for (int i = 0; i < symbolsCount; i++) + { + // + // Requirements ... + string iSymbol = symbols[i]; + ENUM_TIMEFRAMES iPeriod = PERIOD_M5; + + // + // Define Structure ... + X121ProviderDescriptor iDescriptor; + + // + iDescriptor.symbol = iSymbol; + iDescriptor.period = iPeriod; + iDescriptor.staticVolume = x121EAVolume; + iDescriptor.allowLong = x121EAAllowLong; + iDescriptor.allowShort = x121EAAllowShort; + Copy( + signallers, + iDescriptor.signallers); + + // + // Set Inputs to Default ... + iDescriptor.inputs.Default(); + + // + // Prepare Input Requirements ... + + // + iDescriptor.inputs.symbol = iSymbol; + iDescriptor.inputs.period = iPeriod; + + // + ConfigureDescriptor(iDescriptor); + + // + ApplyPreDefineConfigurations(iDescriptor); + + // + // Init Inputs ... + result = iDescriptor.inputs.Init(); + if (!result) + { + return result; + } + + // + // Validate Inputs ... + bool isInputsValid = iDescriptor.inputs.IsValid(); + if (!isInputsValid) + { + continue; + } + + // + result = mX121EA.AddProvider(iDescriptor); + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Configurators ... + +// +// Configuring Descriptors ... +void ConfigureDescriptor( + X121ProviderDescriptor &iDescriptor // +) +{ + // + // XHK ... + iDescriptor.inputs.tmInputs.showLine = false; + + // + // XAMA ... + iDescriptor.inputs.amaInputs.showLine = false; + + // + // XHK ... + iDescriptor.inputs.hkInputs.drawHikenAshi = false; + iDescriptor.inputs.hkInputs.drawSmoothedHikenAshi = false; + + // + // XMRB ... + iDescriptor.inputs.mrbInputs.showFastMa = false; + iDescriptor.inputs.mrbInputs.showSlowMa = false; + iDescriptor.inputs.mrbInputs.showRibbon = false; + + // + // XMC ... + iDescriptor.inputs.mcInputs.showFastMa = false; + iDescriptor.inputs.mcInputs.showSlowMa = false; + iDescriptor.inputs.mcInputs.showVerifierMa = false; + + // + // XICH ... + iDescriptor.inputs.ichInputs.showKumo = false; + iDescriptor.inputs.ichInputs.showKijunSen = false; + iDescriptor.inputs.ichInputs.showTenkanSen = false; + iDescriptor.inputs.ichInputs.showChikouSpan = false; + iDescriptor.inputs.ichInputs.showSenkouSpanA = false; + iDescriptor.inputs.ichInputs.showSenkouSpanB = false; + iDescriptor.inputs.ichInputs.showKijunSenPlus = false; + iDescriptor.inputs.ichInputs.showKijunSenNegative = false; + + // + // XCHE ... + iDescriptor.inputs.cheInputs.showLongExit1Line = false; + iDescriptor.inputs.cheInputs.showShortExit1Line = false; + iDescriptor.inputs.cheInputs.showLongExit2Line = false; + iDescriptor.inputs.cheInputs.showShortExit2Line = false; + + // + // XPV ... + iDescriptor.inputs.pvInputs.showPeaksAndVales = false; + iDescriptor.inputs.pvInputs.showLevels = false; + iDescriptor.inputs.pvInputs.showConsolidations = false; + iDescriptor.inputs.pvInputs.showFibo1Levels = false; + iDescriptor.inputs.pvInputs.showFibo2Levels = false; + iDescriptor.inputs.pvInputs.showFibo3Levels = false; + iDescriptor.inputs.pvInputs.showFibo4Levels = false; + iDescriptor.inputs.pvInputs.showFibo5Levels = false; + + // + // XZG ... + iDescriptor.inputs.zgInputs.showZigZag = false; + iDescriptor.inputs.zgInputs.showPeaksAndVales = false; + + // + // XDON ... + iDescriptor.inputs.donInputs.showOpen = false; + iDescriptor.inputs.donInputs.showHigh = false; + iDescriptor.inputs.donInputs.showClose = false; + iDescriptor.inputs.donInputs.showLow = false; + + // + // XSTR ... + iDescriptor.inputs.strInputs.showTrends = false; + iDescriptor.inputs.strInputs.fillTrends = false; + + // + // Short MArket ... + iDescriptor.inputs.sMarketPeriod = NULL; + iDescriptor.inputs.sMarketMethod = X_PERIOD_AUTO; + + // + // Medium Market ... + iDescriptor.inputs.mMarketPeriod = NULL; + iDescriptor.inputs.mMarketMethod = X_PERIOD_AUTO; + + // + // Long Market ... + iDescriptor.inputs.lMarketPeriod = NULL; + iDescriptor.inputs.lMarketMethod = X_PERIOD_AUTO; + + // + int fontSize = 12; + double fontAngel = 90; + string fontName = "Arial"; + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER; + + // + // Current Market ... + ConfigureCurrentMarketDrawSpecs( + // + iDescriptor, + // + "Current", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Short Market ... + ConfigureShortMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.sMarketPeriod, + iDescriptor.inputs.sMarketMethod, + // + "Short", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Medium Market ... + ConfigureMediumMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.mMarketPeriod, + iDescriptor.inputs.mMarketMethod, + // + "Medium", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Long Market ... + ConfigureLongMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.lMarketPeriod, + iDescriptor.inputs.lMarketMethod, + // + "Long", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Hind Market ... + ConfigureHindMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.hMarketPeriod, + iDescriptor.inputs.hMarketMethod, + // + "Hind", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); +} + +// +// Current ... +void ConfigureCurrentMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + string prefix = "Current", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.cMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Short ... +void ConfigureShortMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Short", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Short Market ... + iDescriptor.inputs.sMarketPeriod = period; + iDescriptor.inputs.sMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.sMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Medium ... +void ConfigureMediumMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Medium", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Medium Market ... + iDescriptor.inputs.mMarketPeriod = period; + iDescriptor.inputs.mMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.mMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Long ... +void ConfigureLongMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Long", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Long Market ... + iDescriptor.inputs.lMarketPeriod = period; + iDescriptor.inputs.lMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.lMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Hind ... +void ConfigureHindMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Hind", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Hind Market ... + iDescriptor.inputs.hMarketPeriod = period; + iDescriptor.inputs.hMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.hMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Configure Market ... +void ConfigureMarketDrawSpecs( + X121MCycleInputs &inputs, + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string prefix = "", + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + inputs.drawLabels = drawLabels; + inputs.drawCBar = drawCBar; + inputs.drawPBar = drawPBar; + inputs.drawCBarMid = drawCBarMid; + inputs.drawPBarMid = drawPBarMid; + inputs.cBarDrawSpecs.Default(); + inputs.pBarDrawSpecs.Default(); + + // + if (drawCBarMid) + { + inputs.cBarMidDrawSpecs.clr = clrYellow; + } + + // + if (drawPBarMid) + { + inputs.pBarMidDrawSpecs.clr = clrYellow; + } + + // + if (drawLabels) + { + // + string cBarStr = prefix + " " + cBarPrefix + " "; + string pBarStr = prefix + " " + pBarPrefix + " "; + + // + if (drawCBar) + { + // + inputs.cBarDrawSpecs.openStyle.Label( + cBarStr + openLabel, + inputs.cBarDrawSpecs.openStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.cBarDrawSpecs.highStyle.Label( + cBarStr + highLabel, + inputs.cBarDrawSpecs.highStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.cBarDrawSpecs.closeStyle.Label( + cBarStr + closeLabel, + inputs.cBarDrawSpecs.closeStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.cBarDrawSpecs.lowStyle.Label( + cBarStr + lowLabel, + inputs.cBarDrawSpecs.lowStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + + // + if (drawPBar) + { + // + inputs.pBarDrawSpecs.openStyle.Label( + pBarStr + openLabel, + inputs.pBarDrawSpecs.openStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.pBarDrawSpecs.highStyle.Label( + pBarStr + highLabel, + inputs.pBarDrawSpecs.highStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.pBarDrawSpecs.closeStyle.Label( + pBarStr + closeLabel, + inputs.pBarDrawSpecs.closeStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.pBarDrawSpecs.lowStyle.Label( + pBarStr + lowLabel, + inputs.pBarDrawSpecs.lowStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + + // + if (drawCBarMid) + { + // + inputs.cBarMidDrawSpecs.Label( + cBarStr + midLineLabel, + clrYellow, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + + // + if (drawPBarMid) + { + // + inputs.pBarMidDrawSpecs.Label( + pBarStr + midLineLabel, + clrYellow, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + } +} + +// +void ApplyPreDefineConfigurations(X121ProviderDescriptor &iDescriptor) +{ + // + bool isX786 = false; + bool isX121 = true; + + // + if (isX786) + { + } + + // + if (isX121) + { + // + iDescriptor.inputs.mrbInputs.showFastMa = isX121; + iDescriptor.inputs.mrbInputs.showSlowMa = isX121; + iDescriptor.inputs.mrbInputs.showRibbon = isX121 && false; + + // + iDescriptor.inputs.mcInputs.showFastMa = isX121; + iDescriptor.inputs.mcInputs.showSlowMa = isX121; + iDescriptor.inputs.mcInputs.showVerifierMa = isX121; + + // + iDescriptor.inputs.cheInputs.showLongExit1Line = isX121; + iDescriptor.inputs.cheInputs.showShortExit1Line = isX121; + iDescriptor.inputs.cheInputs.showLongExit2Line = isX121; + iDescriptor.inputs.cheInputs.showShortExit2Line = isX121; + } +} + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xama.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xama.helper.mq5 new file mode 100644 index 0000000..227800b --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xama.helper.mq5 @@ -0,0 +1,317 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXAMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XAMA_BUFFERS +{ + XAMA_MAIN_LINE = 0 +}; + +// +// Input Models ... +struct XAMAInputs +{ + // + // Props ... + // + // Market ... + int length; // Period + int fastEMA; // Fast EMA Period + int slowEMA; // Slow EMA Period + int maShift; // Shift + ENUM_APPLIED_PRICE appliedTo; // Applied To + // + // Presentation ... + bool showLine; // Show Line + + // + // Constructor(s) ... + XAMAInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + fastEMA = 0; + slowEMA = 0; + maShift = 0; + showLine = false; + appliedTo = PRICE_CLOSE; + } + + // + // Default ... + void Default() + { + // + length = 18; + fastEMA = 2; + slowEMA = 30; + maShift = 0; + showLine = true; + appliedTo = PRICE_CLOSE; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length > 0 && + fastEMA > 0 && + slowEMA > 0 && + slowEMA > fastEMA + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(length, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXAMAHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXAMAHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXAMAHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XAMAInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(mainBuffer, true); + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xama", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, // Period + mInputs.fastEMA, // Fast EMA Period + mInputs.slowEMA, // Slow EMA Period + mInputs.maShift, // Shift + mInputs.appliedTo, // Applied To + // + // Presentation ... + "", + mInputs.showLine // Show Line + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XAMAInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XAMAInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetMain( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mainBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mainBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMain( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mainBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XAMAInputs mInputs; // Inputs ... + + // + // Buffers ... + double mainBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Main Buffer ... + CopyBuffer( + mHandler, + XAMA_MAIN_LINE, + 0, + totalBars, + mainBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xcc.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xcc.helper.mq5 new file mode 100644 index 0000000..98bec86 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xcc.helper.mq5 @@ -0,0 +1,245 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +// Input Models ... +struct XCCInputs +{ + // + // Props ... + + // + // Chart Style ... + ENUM_CHART_MODE mode; // Mode + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + + // + // Presentation ... + bool showCandles; // Show Candles + + // + // Constructor(s) ... + XCCInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + mode = CHART_CANDLES; + + // + upColor = CLR_NONE; + downColor = CLR_NONE; + lineColor = CLR_NONE; + bearishColor = CLR_NONE; + bullishColor = CLR_NONE; + volumesColor = CLR_NONE; + + // + showCandles = false; + } + + // + // Default ... + void Default() + { + // + mode = CHART_CANDLES; + + // + upColor = clrLime; + downColor = clrRed; + lineColor = clrLime; + bearishColor = clrRed; + bullishColor = clrLime; + volumesColor = clrGreen; + // + showCandles = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + true + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, 0); + + // + return result; + } +}; + +// +// Class ... +class XSCXCCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCCHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCCHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCCInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xcc", + // + // Inputs ... + // + // Chart Style ... + "", + mInputs.mode, // Mode + mInputs.upColor, // Up Color + mInputs.downColor, // Down Color + mInputs.lineColor, // Line mode and Doji candlestick Color + mInputs.bearishColor, // Bullish Color + mInputs.bullishColor, // Bearish Color + mInputs.volumesColor, // Volumes Color + // + // Presentation ... + "", + mInputs.showCandles // Show Candles + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCCInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCCInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCCInputs mInputs; // Inputs ... +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xche.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xche.helper.mq5 new file mode 100644 index 0000000..268fc29 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xche.helper.mq5 @@ -0,0 +1,514 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHEHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XCHE_BUFFERS +{ + X_CHE_LONG_EXIT_1_LINE = 0, + X_CHE_SHORT_EXIT_1_LINE = 1, + X_CHE_LONG_EXIT_2_LINE = 2, + X_CHE_SHORT_EXIT_2_LINE = 3, +}; + +// +// Input Models ... +struct XCHEInputs +{ + // + // Props ... + + // + // Market ... + int length; // Length + int loopback; // Loopback + double multiplier1; // 1st Multiplier + double multiplier2; // 2nd Multiplier + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied To + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied To + + // + // Presentation ... + bool showLongExit1Line; // Show 1st Long Exit + bool showShortExit1Line; // Show 1st Short Exit + bool showLongExit2Line; // Show 2st Long Exit + bool showShortExit2Line; // Show 2st Short Exit + + // + // Constructor(s) ... + XCHEInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + loopback = 0; + multiplier1 = 0; + multiplier2 = 0; + + // + upAppliedTo = PRICE_HIGH; + downAppliedTo = PRICE_LOW; + + // + showLongExit1Line = false; + showShortExit1Line = false; + showLongExit2Line = false; + showShortExit2Line = false; + } + + // + // Default ... + void Default() + { + // + length = 35; + loopback = 26; + multiplier1 = 3.0; + multiplier2 = 3.5; + + // + upAppliedTo = PRICE_HIGH; + downAppliedTo = PRICE_LOW; + + // + showLongExit1Line = true; + showShortExit1Line = true; + showLongExit2Line = true; + showShortExit2Line = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length > 0 && + loopback < length && + multiplier1 > 0 && + multiplier2 > multiplier1 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(length, loopback); + + // + return result; + } +}; + +// +// Class ... +class XSCXCHEHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCHEHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCHEHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCHEInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(longExit1Buffer, true); + ArraySetAsSeries(longExit2Buffer, true); + ArraySetAsSeries(shortExit1Buffer, true); + ArraySetAsSeries(shortExit2Buffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xche", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, + mInputs.loopback, + mInputs.multiplier1, + mInputs.multiplier2, + // + // Calculations ... + "", + mInputs.upAppliedTo, + mInputs.downAppliedTo, + // + // Presentation ... + "", + mInputs.showLongExit1Line, // Show 1st Long Exit, + mInputs.showShortExit1Line, // Show 1st Short Exit, + mInputs.showLongExit2Line, // Show 2st Long Exit, + mInputs.showShortExit2Line // Show 2st Short Exit + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCHEInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCHEInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs); + } + + // + // Buffers ... + + // + double GetLongExit1( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return longExit1Buffer[barIndex]; + } + + // + // Copy Required Long Exits 1 ... + int CopyLongExit1( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + longExit1Buffer, + buffer, + forceClean + // + ); + } + + // + double GetLongExit2( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return longExit2Buffer[barIndex]; + } + + // + // Copy Required Long Exits 2 ... + int CopyLongExit2( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + longExit2Buffer, + buffer, + forceClean + // + ); + } + + // + double GetShortExit1( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return shortExit1Buffer[barIndex]; + } + + // + // Copy Required Short Exits 1 ... + int CopyShortExit1( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + shortExit1Buffer, + buffer, + forceClean + // + ); + } + + // + double GetShortExit2( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return shortExit2Buffer[barIndex]; + } + + // + // Copy Required Short Exits 2 ... + int CopyShortExit2( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + shortExit2Buffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCHEInputs mInputs; // Inputs ... + + // + // Buffers ... + // + double longExit1Buffer[]; + double longExit2Buffer[]; + double shortExit1Buffer[]; + double shortExit2Buffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + int calculatedBars = CountCalculatedBars(); + + // + // Long Exit 1 ... + CopyBuffer( + mHandler, + X_CHE_LONG_EXIT_1_LINE, + 0, + totalBars, + longExit1Buffer + // + ); + + // + // Long Exit 2 ... + CopyBuffer( + mHandler, + X_CHE_LONG_EXIT_2_LINE, + 0, + totalBars, + longExit2Buffer + // + ); + + // + // Short Exit 1 ... + CopyBuffer( + mHandler, + X_CHE_SHORT_EXIT_1_LINE, + 0, + totalBars, + shortExit1Buffer + // + ); + + // + // Short Exit 2 ... + CopyBuffer( + mHandler, + X_CHE_SHORT_EXIT_2_LINE, + 0, + totalBars, + shortExit2Buffer + // + ); + } +}; + +// +// Tools ... diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchlh.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchlh.helper.mq5 new file mode 100644 index 0000000..f67f902 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchlh.helper.mq5 @@ -0,0 +1,967 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHLHHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XCHLH_BUFFERS +{ + // + // LC ... + XCHLH_LC_HH_LINE = 0, + XCHLH_LC_LL_LINE = 1, + // + // MC ... + XCHLH_MC_HH_LINE = 2, + XCHLH_MC_LL_LINE = 3, + // + // SC ... + XCHLH_SC_HH_LINE = 4, + XCHLH_SC_LL_LINE = 5, + // + // Hot State ... + XCHLH_HOT_STATE_LINE = 6 +}; + +// +// Input Models ... +struct XCHLHInputs +{ + // + // Props ... + + // + // Hot Areas ... + bool drawHotAreas; // Draw Hot Areas Symbol + uchar hotHHArrowCode; // Hot HH Arrow Code + color hotHHArrowColor; // Hot HH Arrow Color + uchar hotLLArrowCode; // Hot LL Arrow Code + color hotLLArrowColor; // Hot LL Arrow Color + + // + // Long Cycle ... + // LC Market ... + int lcLength; // Length + double lcThresholdInPips; // Threshold In Pips + ENUM_SERIESMODE lcHHMode; // Highest High Calculation Method + ENUM_SERIESMODE lcLLMode; // Lowest Low Calculation Method + // + // LC Style ... + int lcDrawWidth; // Draw Width + ENUM_DRAW_TYPE lcDrawType; // Draw Type + ENUM_LINE_STYLE lcDrawStyle; // Draw Style + color lcHHColor; // Highest High Color + color lcLLColor; // Lowest Low Color + // LC Drawings ... + bool lcDrawHH; // Draw Highest High + bool lcDrawLL; // Draw Lowest Low + + // + // Medium Cycle ... + // MC Market ... + int mcLength; // Length + double mcThresholdInPips; // Threshold In Pips + ENUM_SERIESMODE mcHHMode; // Highest High Calculation Method + ENUM_SERIESMODE mcLLMode; // Lowest Low Calculation Method + // MC Style ... + int mcDrawWidth; // Draw Width + ENUM_DRAW_TYPE mcDrawType; // Draw Type + ENUM_LINE_STYLE mcDrawStyle; // Draw Style + color mcHHColor; // Highest High Color + color mcLLColor; // Lowest Low Color + // MC Drawings ... + bool mcDrawHH; // Draw Highest High + bool mcDrawLL; // Draw Lowest Low + + // + // Short Cycle ... + // SC Market ... + int scLength; // Length + double scThresholdInPips; // Threshold In Pips + ENUM_SERIESMODE scHHMode; // Highest High Calculation Method + ENUM_SERIESMODE scLLMode; // Lowest Low Calculation Method + // SC Style ... + int scDrawWidth; // Draw Width + ENUM_DRAW_TYPE scDrawType; // Draw Type + ENUM_LINE_STYLE scDrawStyle; // Draw Style + color scHHColor; // Highest High Color + color scLLColor; // Lowest Low Color + // SC Drawings ... + bool scDrawHH; // Draw Highest High + bool scDrawLL; // Draw Lowest Low + + // + // Constructor(s) ... + XCHLHInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Hot Areas ... + drawHotAreas = false; + hotHHArrowCode = 234; + hotHHArrowColor = CLR_NONE; + hotLLArrowCode = 233; + hotLLArrowColor = CLR_NONE; + + // + // Long Cycle ... + // LC Market ... + lcLength = 0; + lcThresholdInPips = 0; + lcHHMode = MODE_HIGH; + lcLLMode = MODE_LOW; + // + // LC Style ... + lcDrawWidth = 1; + lcDrawType = DRAW_NONE; + lcDrawStyle = STYLE_DOT; + lcHHColor = CLR_NONE; + lcLLColor = CLR_NONE; + // LC Drawings ... + lcDrawHH = false; + lcDrawLL = false; + + // + // Medium Cycle ... + // MC Market ... + mcLength = 0; + mcThresholdInPips = 0; + mcHHMode = MODE_HIGH; + mcLLMode = MODE_LOW; + // MC Style ... + mcDrawWidth = 1; + mcDrawType = DRAW_NONE; + mcDrawStyle = STYLE_DOT; + mcHHColor = CLR_NONE; + mcLLColor = CLR_NONE; + // MC Drawings ... + mcDrawHH = false; + mcDrawLL = false; + + // + // Short Cycle ... + // SC Market ... + scLength = 0; + scThresholdInPips = 0; + scHHMode = MODE_HIGH; + scLLMode = MODE_LOW; + // SC Style ... + scDrawWidth = 1; + scDrawType = DRAW_NONE; + scDrawStyle = STYLE_DOT; + scHHColor = CLR_NONE; + scLLColor = CLR_NONE; + // SC Drawings ... + scDrawHH = false; + scDrawLL = false; + } + + // + // Default ... + void Default() + { + // + // Hot Areas ... + drawHotAreas = false; + hotHHArrowCode = 234; + hotHHArrowColor = CLR_NONE; + hotLLArrowCode = 233; + hotLLArrowColor = CLR_NONE; + + // + // Long Cycle ... + // LC Market ... + lcLength = 28; + lcThresholdInPips = 0.3; + lcHHMode = MODE_HIGH; + lcLLMode = MODE_LOW; + // + // LC Style ... + lcDrawWidth = 1; + lcDrawType = DRAW_LINE; + lcDrawStyle = STYLE_DOT; + lcHHColor = clrAqua; + lcLLColor = clrFuchsia; + // LC Drawings ... + lcDrawHH = false; + lcDrawLL = false; + + // + // Medium Cycle ... + // MC Market ... + mcLength = 14; + mcThresholdInPips = 0.3; + mcHHMode = MODE_HIGH; + mcLLMode = MODE_LOW; + // MC Style ... + mcDrawWidth = 1; + mcDrawType = DRAW_LINE; + mcDrawStyle = STYLE_DOT; + mcHHColor = clrLime; + mcLLColor = clrRed; + // MC Drawings ... + mcDrawHH = false; + mcDrawLL = false; + + // + // Short Cycle ... + // SC Market ... + scLength = 7; + scThresholdInPips = 0.3; + scHHMode = MODE_HIGH; + scLLMode = MODE_LOW; + // SC Style ... + scDrawWidth = 1; + scDrawType = DRAW_LINE; + scDrawStyle = STYLE_DOT; + scHHColor = clrLightBlue; + scLLColor = clrLightSalmon; + // SC Drawings ... + scDrawHH = false; + scDrawLL = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + // LC ... + (lcLength >= 4 && + lcLength > mcLength && + lcLength > scLength) + // + && + // + // MC ... + (mcLength >= 4 && + mcLength > scLength && + mcLength < lcLength) + // + && + // + // SC ... + (scLength >= 4 && + scLength < mcLength && + scLength < lcLength) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(lcLength, mcLength); + result = MathMax(result, scLength); + + // + return result; + } +}; + +// +// Class ... +class XSCXCHLHHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCHLHHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCHLHHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCHLHInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(scHHBuffer, true); + ArraySetAsSeries(scLLBuffer, true); + ArraySetAsSeries(mcHHBuffer, true); + ArraySetAsSeries(mcLLBuffer, true); + ArraySetAsSeries(lcHHBuffer, true); + ArraySetAsSeries(lcLLBuffer, true); + ArraySetAsSeries(hotStateBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xchlh", + // + // Inputs ... + // + // Hot Areas ... + "", + // + mInputs.drawHotAreas, // Draw Hot Areas Symbol + mInputs.hotHHArrowCode, // Hot HH Arrow Code + mInputs.hotHHArrowColor, // Hot HH Arrow Color + mInputs.hotLLArrowCode, // Hot LL Arrow Code + mInputs.hotLLArrowColor, // Hot LL Arrow Color + // + // Long Cycle ... + "", + // LC Market ... + "", + // + mInputs.lcLength, // Length + mInputs.lcThresholdInPips, // Threshold In Pips + mInputs.lcHHMode, // Highest High Calculation Method + mInputs.lcLLMode, // Lowest Low Calculation Method + // + // LC Style ... + "", + // + mInputs.lcDrawWidth, // Draw Width + mInputs.lcDrawType, // Draw Type + mInputs.lcDrawStyle, // Draw Style + mInputs.lcHHColor, // Highest High Color + mInputs.lcLLColor, // Lowest Low Color + // + // LC Drawings ... + "", + mInputs.lcDrawHH, // Draw Highest High + mInputs.lcDrawLL, // Draw Lowest Low + // + // Medium Cycle ... + "", + // MC Market ... + "", + // + mInputs.mcLength, // Length + mInputs.mcThresholdInPips, // Threshold In Pips + mInputs.mcHHMode, // Highest High Calculation Method + mInputs.mcLLMode, // Lowest Low Calculation Method + // + // MC Style ... + "", + // + mInputs.mcDrawWidth, // Draw Width + mInputs.mcDrawType, // Draw Type + mInputs.mcDrawStyle, // Draw Style + mInputs.mcHHColor, // Highest High Color + mInputs.mcLLColor, // Lowest Low Color + // + // MC Drawings ... + "", + mInputs.mcDrawHH, // Draw Highest High + mInputs.mcDrawLL, // Draw Lowest Low + // + // Short Cycle ... + "", + // SC Market ... + "", + // + mInputs.scLength, // Length + mInputs.scThresholdInPips, // Threshold In Pips + mInputs.scHHMode, // Highest High Calculation Method + mInputs.scLLMode, // Lowest Low Calculation Method + // + // SC Style ... + "", + // + mInputs.scDrawWidth, // Draw Width + mInputs.scDrawType, // Draw Type + mInputs.scDrawStyle, // Draw Style + mInputs.scHHColor, // Highest High Color + mInputs.scLLColor, // Lowest Low Color + // + // SC Drawings ... + "", + mInputs.scDrawHH, // Draw Highest High + mInputs.scDrawLL // Draw Lowest Low + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCHLHInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCHLHInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Short ... + + // + double GetSCHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(scHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return scHHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySCHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + scHHBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSCLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(scLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return scLLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySCLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + scLLBuffer, + buffer, + forceClean + // + ); + } + + // + // Medium ... + + // + double GetMCHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mcHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mcHHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMCHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mcHHBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMCLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mcLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mcLLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMCLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mcLLBuffer, + buffer, + forceClean + // + ); + } + + // + // Long ... + + // + double GetLCHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lcHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lcHHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLCHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lcHHBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLCLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lcLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lcLLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLCLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lcLLBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHotState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hotStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hotStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHotState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hotStateBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCHLHInputs mInputs; // Inputs ... + + // + // Buffers ... + double scHHBuffer[]; + double scLLBuffer[]; + double mcHHBuffer[]; + double mcLLBuffer[]; + double lcHHBuffer[]; + double lcLLBuffer[]; + double hotStateBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Short Cycle ... + + // + // HH ... + CopyBuffer( + mHandler, + XCHLH_SC_HH_LINE, + 0, + totalBars, + scHHBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XCHLH_SC_LL_LINE, + 0, + totalBars, + scLLBuffer + // + ); + + // + // Medium Cycle ... + + // + // HH ... + CopyBuffer( + mHandler, + XCHLH_MC_HH_LINE, + 0, + totalBars, + mcHHBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XCHLH_MC_LL_LINE, + 0, + totalBars, + mcLLBuffer + // + ); + + // + // Long Cycle ... + + // + // HH ... + CopyBuffer( + mHandler, + XCHLH_LC_HH_LINE, + 0, + totalBars, + lcHHBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XCHLH_LC_LL_LINE, + 0, + totalBars, + lcLLBuffer + // + ); + + // + // Hot State ... + CopyBuffer( + mHandler, + XCHLH_HOT_STATE_LINE, + 0, + totalBars, + hotStateBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchma.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchma.helper.mq5 new file mode 100644 index 0000000..b18120a --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xchma.helper.mq5 @@ -0,0 +1,960 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XCHMA_BUFFERS +{ + // + // LC ... + XCHMA_LC_FAST_LINE = 0, + XCHMA_LC_SLOW_LINE = 1, + // + // MC ... + XCHMA_MC_FAST_LINE = 2, + XCHMA_MC_SLOW_LINE = 3, + // + // SC ... + XCHMA_SC_FAST_LINE = 4, + XCHMA_SC_SLOW_LINE = 5, + // + XCHMA_HOT_STATE_LINE = 6, +}; + +// +// Input Models ... +struct XCHMAInputs +{ + // + // Props ... + // + // Hot Areas ... + bool drawHotAreas; // Draw Hot Areas Symbol + uchar hotBullishArrowCode; // Hot Bullish Arrow Code + color hotBullishArrowColor; // Hot Bullish Arrow Color + uchar hotBearishArrowCode; // Hot Bearish Arrow Code + color hotBearishArrowColor; // Hot Bearish Arrow Color + + // + // Long Cycle ... + // LC Market ... + int lcFastLength; // Fast Length + int lcSlowLength; // Slow Length + ENUM_MA_METHOD lcMethod; // Calculation Method + ENUM_APPLIED_PRICE lcAppliedTo; // Applied To + // LC Style ... + int lcDrawWidth; // Draw Width + ENUM_DRAW_TYPE lcDrawType; // Draw Type + ENUM_LINE_STYLE lcDrawStyle; // Draw Style + color lcFastColor; // Fast Color + color lcSlowColor; // Slow Color + // LC Drawings ... + bool lcDrawFast; // Draw Fast + bool lcDrawSlow; // Draw Slow + bool lcDrawCrosses; // Draw Cross Lines + + // + // Medium Cycle ... + // MC Market ... + int mcFastLength; // Fast Length + int mcSlowLength; // Slow Length + ENUM_MA_METHOD mcMethod; // Calculation Method + ENUM_APPLIED_PRICE mcAppliedTo; // Applied To + // MC Style ... + int mcDrawWidth; // Draw Width + ENUM_DRAW_TYPE mcDrawType; // Draw Type + ENUM_LINE_STYLE mcDrawStyle; // Draw Style + color mcFastColor; // Fast Color + color mcSlowColor; // Slow Color + // MC Drawings ... + bool mcDrawFast; // Draw Fast + bool mcDrawSlow; // Draw Slow + bool mcDrawCrosses; // Draw Cross Lines + + // + // Short Cycle ... + // SC Market ... + int scFastLength; // Fast Length + int scSlowLength; // Slow Length + ENUM_MA_METHOD scMethod; // Calculation Method + ENUM_APPLIED_PRICE scAppliedTo; // Applied To + // SC Style ... + int scDrawWidth; // Draw Width + ENUM_DRAW_TYPE scDrawType; // Draw Type + ENUM_LINE_STYLE scDrawStyle; // Draw Style + color scFastColor; // Fast Color + color scSlowColor; // Slow Color + // SC Drawings ... + bool scDrawFast; // Draw Fast + bool scDrawSlow; // Draw Slow + bool scDrawCrosses; // Draw Cross Lines + + // + // Constructor(s) ... + XCHMAInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Hot Areas ... + drawHotAreas = false; + hotBullishArrowCode = 228; + hotBullishArrowColor = CLR_NONE; + hotBearishArrowCode = 230; + hotBearishArrowColor = CLR_NONE; + + // + // Long Cycle ... + // LC Market ... + lcFastLength = 20; + lcSlowLength = 50; + lcMethod = MODE_EMA; + lcAppliedTo = PRICE_CLOSE; + // LC Style ... + lcDrawWidth = 1; + lcDrawType = DRAW_NONE; + lcDrawStyle = STYLE_DOT; + lcFastColor = CLR_NONE; + lcSlowColor = CLR_NONE; + // LC Drawings ... + lcDrawFast = false; + lcDrawSlow = false; + lcDrawCrosses = false; + + // + // Medium Cycle ... + // MC Market ... + mcFastLength = 10; + mcSlowLength = 30; + mcMethod = MODE_EMA; + mcAppliedTo = PRICE_CLOSE; + // MC Style ... + mcDrawWidth = 1; + mcDrawType = DRAW_NONE; + mcDrawStyle = STYLE_DOT; + mcFastColor = CLR_NONE; + mcSlowColor = CLR_NONE; + // MC Drawings ... + mcDrawFast = false; + mcDrawSlow = false; + mcDrawCrosses = false; + + // + // Short Cycle ... + // SC Market ... + scFastLength = 7; + scSlowLength = 14; + scMethod = MODE_EMA; + scAppliedTo = PRICE_CLOSE; + // SC Style ... + scDrawWidth = 1; + scDrawType = DRAW_NONE; + scDrawStyle = STYLE_SOLID; + scFastColor = CLR_NONE; + scSlowColor = CLR_NONE; + // SC Drawings ... + scDrawFast = false; + scDrawSlow = false; + scDrawCrosses = false; + } + + // + // Default ... + void Default() + { + // + // Hot Areas ... + drawHotAreas = false; + hotBullishArrowCode = 228; + hotBullishArrowColor = CLR_NONE; + hotBearishArrowCode = 230; + hotBearishArrowColor = CLR_NONE; + + // + // Long Cycle ... + // LC Market ... + lcFastLength = 20; + lcSlowLength = 50; + lcMethod = MODE_EMA; + lcAppliedTo = PRICE_CLOSE; + // LC Style ... + lcDrawWidth = 1; + lcDrawType = DRAW_LINE; + lcDrawStyle = STYLE_DOT; + lcFastColor = clrAqua; + lcSlowColor = clrFuchsia; + // LC Drawings ... + lcDrawFast = false; + lcDrawSlow = false; + lcDrawCrosses = false; + + // + // Medium Cycle ... + // MC Market ... + mcFastLength = 10; + mcSlowLength = 30; + mcMethod = MODE_EMA; + mcAppliedTo = PRICE_CLOSE; + // MC Style ... + mcDrawWidth = 1; + mcDrawType = DRAW_LINE; + mcDrawStyle = STYLE_DOT; + mcFastColor = clrLime; + mcSlowColor = clrRed; + // MC Drawings ... + mcDrawFast = false; + mcDrawSlow = false; + mcDrawCrosses = false; + + // + // Short Cycle ... + // SC Market ... + scFastLength = 7; + scSlowLength = 14; + scMethod = MODE_EMA; + scAppliedTo = PRICE_CLOSE; + // SC Style ... + scDrawWidth = 1; + scDrawType = DRAW_LINE; + scDrawStyle = STYLE_SOLID; + scFastColor = clrLightBlue; + scSlowColor = clrLightSalmon; + // SC Drawings ... + scDrawFast = false; + scDrawSlow = false; + scDrawCrosses = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + (lcFastLength >= 4 && lcSlowLength > lcFastLength) && + (mcFastLength >= 4 && mcSlowLength > mcFastLength) && + (scFastLength >= 4 && scSlowLength > scFastLength) && + (lcFastLength > mcFastLength && + mcFastLength > scFastLength) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(scFastLength, scSlowLength); + result = MathMax(result, lcFastLength); + result = MathMax(result, lcSlowLength); + result = MathMax(result, mcFastLength); + result = MathMax(result, mcSlowLength); + + // + return result; + } +}; + +// +// Class ... +class XSCXCHMAHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCHMAHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCHMAHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCHMAInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(scFastBuffer, true); + ArraySetAsSeries(scSlowBuffer, true); + ArraySetAsSeries(mcFastBuffer, true); + ArraySetAsSeries(mcSlowBuffer, true); + ArraySetAsSeries(lcFastBuffer, true); + ArraySetAsSeries(lcSlowBuffer, true); + ArraySetAsSeries(hotStateBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xchma", + // + // Inputs ... + // + // Hot Areas ... + "", + mInputs.drawHotAreas, // Draw Hot Areas Symbol + mInputs.hotBullishArrowCode, // Hot Bullish Arrow Code + mInputs.hotBullishArrowColor, // Hot Bullish Arrow Color + mInputs.hotBearishArrowCode, // Hot Bearish Arrow Code + mInputs.hotBearishArrowColor, // Hot Bearish Arrow Color + // + // Long Cycle ... + "", + // + // LC Market ... + "", + mInputs.lcFastLength, // Fast Length + mInputs.lcSlowLength, // Slow Length + mInputs.lcMethod, // Calculation Method + mInputs.lcAppliedTo, // Applied To + // + // LC Style ... + "", + mInputs.lcDrawWidth, // Draw Width + mInputs.lcDrawType, // Draw Type + mInputs.lcDrawStyle, // Draw Style + mInputs.lcFastColor, // Fast Color + mInputs.lcSlowColor, // Slow Color + // + // LC Drawings ... + "", + mInputs.lcDrawFast, // Draw Fast + mInputs.lcDrawSlow, // Draw Slow + mInputs.lcDrawCrosses, // Draw Cross Lines + // + // Medium Cycle ... + "", + // + // MC Market ... + "", + mInputs.mcFastLength, // Fast Length + mInputs.mcSlowLength, // Slow Length + mInputs.mcMethod, // Calculation Method + mInputs.mcAppliedTo, // Applied To + // + // MC Style ... + "", + mInputs.mcDrawWidth, // Draw Width + mInputs.mcDrawType, // Draw Type + mInputs.mcDrawStyle, // Draw Style + mInputs.mcFastColor, // Fast Color + mInputs.mcSlowColor, // Slow Color + // + // MC Drawings ... + "", + mInputs.mcDrawFast, // Draw Fast + mInputs.mcDrawSlow, // Draw Slow + mInputs.mcDrawCrosses, // Draw Cross Lines + // + // Short Cycle ... + "", + // + // SC Market ... + "", + mInputs.scFastLength, // Fast Length + mInputs.scSlowLength, // Slow Length + mInputs.scMethod, // Calculation Method + mInputs.scAppliedTo, // Applied To + // + // SC Style ... + "", + mInputs.scDrawWidth, // Draw Width + mInputs.scDrawType, // Draw Type + mInputs.scDrawStyle, // Draw Style + mInputs.scFastColor, // Fast Color + mInputs.scSlowColor, // Slow Color + // + // SC Drawings ... + "", + mInputs.scDrawFast, // Draw Fast + mInputs.scDrawSlow, // Draw Slow + mInputs.scDrawCrosses // Draw Cross Lines + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCHMAInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCHMAInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Short ... + + // + double GetSCFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(scFastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return scFastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySCFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + scFastBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSCSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(scSlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return scSlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySCSlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + scSlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Medium ... + + // + double GetMCFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mcFastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mcFastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMCFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mcFastBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMCSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mcSlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mcSlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMCSlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mcSlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Long ... + + // + double GetLCFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lcFastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lcFastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLCFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lcFastBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLCSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lcSlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lcSlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLCSlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lcSlowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHotState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hotStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hotStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHotState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hotStateBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCHMAInputs mInputs; // Inputs ... + + // + // Buffers ... + double scFastBuffer[]; + double scSlowBuffer[]; + double mcFastBuffer[]; + double mcSlowBuffer[]; + double lcFastBuffer[]; + double lcSlowBuffer[]; + double hotStateBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Short Cycle ... + + // + // Fast ... + CopyBuffer( + mHandler, + XCHMA_SC_FAST_LINE, + 0, + totalBars, + scFastBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + XCHMA_SC_SLOW_LINE, + 0, + totalBars, + scSlowBuffer + // + ); + + // + // Medium Cycle ... + + // + // Fast ... + CopyBuffer( + mHandler, + XCHMA_MC_FAST_LINE, + 0, + totalBars, + mcFastBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + XCHMA_MC_SLOW_LINE, + 0, + totalBars, + mcSlowBuffer + // + ); + + // + // Long Cycle ... + + // + // Fast ... + CopyBuffer( + mHandler, + XCHMA_LC_FAST_LINE, + 0, + totalBars, + lcFastBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + XCHMA_LC_SLOW_LINE, + 0, + totalBars, + lcSlowBuffer + // + ); + + // + // Hot State ... + CopyBuffer( + mHandler, + XCHMA_HOT_STATE_LINE, + 0, + totalBars, + hotStateBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xct.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xct.helper.mq5 new file mode 100644 index 0000000..a7e8769 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xct.helper.mq5 @@ -0,0 +1,220 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCTHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +// Input Models ... +struct XCTInputs +{ + // + // Props ... + + // + color clr; // Text Color + ENUM_BASE_CORNER corner; // Text Position + + // + // Presentation ... + bool showCandleTime; // Show Candle Time + + // + // Constructor(s) ... + XCTInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + clr = CLR_NONE; + corner = CORNER_RIGHT_LOWER; + + // + // Presentation ... + showCandleTime = false; + } + + // + // Default ... + void Default() + { + // + clr = clrYellow; + corner = CORNER_RIGHT_LOWER; + + // + // Presentation ... + showCandleTime = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + true + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, 0); + + // + return result; + } +}; + +// +// Class ... +class XSCXCTHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCTHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCTHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCTInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xct", + // + // Inputs ... + mInputs.clr, // Text Color + mInputs.corner, // Text Position + // + // Presentation ... + "", + mInputs.showCandleTime // Show Candle Time + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCTInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCTInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCTInputs mInputs; // Inputs ... +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xdon.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xdon.helper.mq5 new file mode 100644 index 0000000..3e7355d --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xdon.helper.mq5 @@ -0,0 +1,1075 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXDONHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XDON_BUFFERS +{ + // + // Open ... + XDON_UPPER_O_LINE = 0, + XDON_LOWER_O_LINE = 1, + // + // Close ... + XDON_UPPER_C_LINE = 2, + XDON_LOWER_C_LINE = 3, + // + // High ... + XDON_UPPER_H_LINE = 4, + XDON_LOWER_H_LINE = 5, + // + // Low ... + XDON_UPPER_L_LINE = 6, + XDON_LOWER_L_LINE = 7, +}; + +// +// Input Models ... +struct XDONInputs +{ + // + // Props ... + + // + // Market ... + int length; // Market Length + double offset; // Offset + + // + // Presentation ... + bool showOpen; // Show Open + bool showHigh; // Show High + bool showClose; // Show Close + bool showLow; // Show Low + + // + // Constructor(s) ... + XDONInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + length = 0; + offset = 0; + + // + // Presentation ... + showOpen = false; + showHigh = false; + showClose = false; + showLow = false; + } + + // + // Default ... + void Default() + { + // + // Market ... + length = 52; + offset = 0; + + // + // Presentation ... + showOpen = true; + showHigh = true; + showClose = true; + showLow = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 5 && + offset >= 0 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXDONHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXDONHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXDONHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XDONInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(upperOBuffer, true); + ArraySetAsSeries(lowerOBuffer, true); + ArraySetAsSeries(upperCBuffer, true); + ArraySetAsSeries(lowerCBuffer, true); + ArraySetAsSeries(upperHBuffer, true); + ArraySetAsSeries(lowerHBuffer, true); + ArraySetAsSeries(upperLBuffer, true); + ArraySetAsSeries(lowerLBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xdon", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, // Market Length + mInputs.offset, // Offset + // + // Presentation ... + "", + mInputs.showOpen, // Show Open + mInputs.showHigh, // Show High + mInputs.showClose, // Show Close + mInputs.showLow // Show Low + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XDONInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XDONInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Open ... + + // + // Upper ... + + // + double GetUpperO( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(upperOBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return upperOBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyUpperO( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + upperOBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameUpperO( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + upperOBuffer, + verifier, + barIndex // + ); + } + + // + // Lower ... + + // + double GetLowerO( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lowerOBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lowerOBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLowerO( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lowerOBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameLowerO( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + lowerOBuffer, + verifier, + barIndex // + ); + } + + // + // Close ... + + // + // Upper ... + + // + double GetUpperC( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(upperCBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return upperCBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyUpperC( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + upperCBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameUpperC( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + upperCBuffer, + verifier, + barIndex // + ); + } + + // + // Lower ... + + // + double GetLowerC( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lowerCBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lowerCBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLowerC( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lowerCBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameLowerC( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + lowerCBuffer, + verifier, + barIndex // + ); + } + + // + // High ... + + // + // Upper ... + + // + double GetUpperH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(upperHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return upperHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyUpperH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + upperHBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameUpperH( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + upperHBuffer, + verifier, + barIndex // + ); + } + + // + // Lower ... + + // + double GetLowerH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lowerHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lowerHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLowerH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lowerHBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameLowerH( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + lowerHBuffer, + verifier, + barIndex // + ); + } + + // + // Low ... + + // + // Upper ... + + // + double GetUpperL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(upperLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return upperLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyUpperL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + upperLBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameUpperL( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + upperLBuffer, + verifier, + barIndex // + ); + } + + // + // Lower ... + + // + double GetLowerL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lowerLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lowerLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLowerL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lowerLBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameLowerL( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + lowerLBuffer, + verifier, + barIndex // + ); + } + + // + void GetUppers( + double &result[], + int barIndex = 0 // + ) + { + // + Clean(result); + + // + double uo = GetUpperO(barIndex); + double uc = GetUpperC(barIndex); + double uh = GetUpperH(barIndex); + double ul = GetUpperL(barIndex); + + // + Add(uo, result); + Add(uc, result); + Add(uh, result); + Add(ul, result); + } + double GetMinUpper( + int barIndex = 0 // + ) + { + // + double values[]; + GetUppers(values); + + // + double result = GetMin(values); + + // + return result; + } + double GetMaxUpper( + int barIndex = 0 // + ) + { + // + double values[]; + GetUppers(values); + + // + double result = GetMax(values); + + // + return result; + } + + // + void GetLowers( + double &result[], + int barIndex = 0 // + ) + { + // + Clean(result); + + // + double lo = GetLowerO(barIndex); + double lc = GetLowerC(barIndex); + double lh = GetLowerH(barIndex); + double ll = GetLowerL(barIndex); + + // + Add(lo, result); + Add(lc, result); + Add(lh, result); + Add(ll, result); + } + double GetMinLower( + int barIndex = 0 // + ) + { + // + double values[]; + GetLowers(values); + + // + double result = GetMin(values); + + // + return result; + } + double GetMaxLower( + int barIndex = 0 // + ) + { + // + double values[]; + GetLowers(values); + + // + double result = GetMin(values); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XDONInputs mInputs; // Inputs ... + + // + // Buffers ... + double upperOBuffer[]; + double lowerOBuffer[]; + double upperCBuffer[]; + double lowerCBuffer[]; + double upperHBuffer[]; + double lowerHBuffer[]; + double upperLBuffer[]; + double lowerLBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Open ... + + // + // Upper Buffer ... + CopyBuffer( + mHandler, + XDON_UPPER_O_LINE, + 0, + totalBars, + upperOBuffer + // + ); + + // + // Lower Buffer ... + CopyBuffer( + mHandler, + XDON_LOWER_O_LINE, + 0, + totalBars, + lowerOBuffer + // + ); + + // + // Close ... + + // + // Upper Buffer ... + CopyBuffer( + mHandler, + XDON_UPPER_C_LINE, + 0, + totalBars, + upperCBuffer + // + ); + + // + // Lower Buffer ... + CopyBuffer( + mHandler, + XDON_LOWER_C_LINE, + 0, + totalBars, + lowerCBuffer + // + ); + + // + // High ... + + // + // Upper Buffer ... + CopyBuffer( + mHandler, + XDON_UPPER_H_LINE, + 0, + totalBars, + upperHBuffer + // + ); + + // + // Lower Buffer ... + CopyBuffer( + mHandler, + XDON_LOWER_H_LINE, + 0, + totalBars, + lowerHBuffer + // + ); + + // + // Low ... + + // + // Upper Buffer ... + CopyBuffer( + mHandler, + XDON_UPPER_L_LINE, + 0, + totalBars, + upperLBuffer + // + ); + + // + // Lower Buffer ... + CopyBuffer( + mHandler, + XDON_LOWER_L_LINE, + 0, + totalBars, + lowerLBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xfi.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xfi.helper.mq5 new file mode 100644 index 0000000..c636da6 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xfi.helper.mq5 @@ -0,0 +1,292 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXFIHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XFI_BUFFERS +{ + XFI_MAIN_LINE = 0 +}; + +// +// Input Models ... +struct XFIInputs +{ + // + // Props ... + int length; // Length + ENUM_MA_METHOD method; // MA Method + ENUM_APPLIED_VOLUME appliedTo; // Applied To + + // + // Constructor(s) ... + XFIInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + method = MODE_SMA; + appliedTo = VOLUME_TICK; + } + + // + // Default ... + void Default() + { + // + length = 18; + method = MODE_SMA; + appliedTo = VOLUME_TICK; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 2 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXFIHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXFIHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXFIHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XFIInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(mainBuffer, true); + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xfi", + // + // Inputs ... + mInputs.length, // Length + mInputs.method, // MA Method + mInputs.appliedTo // Applied To + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XFIInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XFIInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetMain( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mainBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mainBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMain( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mainBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XFIInputs mInputs; // Inputs ... + + // + // Buffers ... + double mainBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Short Exit 2 ... + CopyBuffer( + mHandler, + XFI_MAIN_LINE, + 0, + totalBars, + mainBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhk.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhk.helper.mq5 new file mode 100644 index 0000000..c9b2698 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhk.helper.mq5 @@ -0,0 +1,1014 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHKHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XHK_BUFFERS +{ + // + // Hiken Ashi ... + XHK_OPEN_LINE = 0, + XHK_HIGHLINE = 1, + XHK_LOW_LINE = 2, + XHK_CLOSE_LINE = 3, + // + // Smoothed Hiken Ashi ... + XHK_SM_OPEN_LINE = 5, + XHK_SM_HIGHLINE = 6, + XHK_SM_LOW_LINE = 7, + XHK_SM_CLOSE_LINE = 8, +}; + +// +// Input Models ... +struct XHKInputs +{ + // + // Props ... + + // + // Market ... + int smoothingLength; // Smoothing Length + // + // Presentation ... + bool drawHikenAshi; // Draw Hiken Ashi + bool drawSmoothedHikenAshi; // Draw Smoothed Hiken Ashi + + // + // Constructor(s) ... + XHKInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + smoothingLength = 0; + // + // Presentation ... + drawHikenAshi = false; + drawSmoothedHikenAshi = false; + } + + // + // Default ... + void Default() + { + // + // Market ... + smoothingLength = 17; + // + // Presentation ... + drawHikenAshi = true; + drawSmoothedHikenAshi = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + smoothingLength > 2 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, smoothingLength); + + // + return result; + } +}; + +// +// Class ... +class XSCXHKHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXHKHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXHKHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XHKInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(openBuffer, true); + ArraySetAsSeries(highBuffer, true); + ArraySetAsSeries(lowBuffer, true); + ArraySetAsSeries(closeBuffer, true); + ArraySetAsSeries(smOpenBuffer, true); + ArraySetAsSeries(smHighBuffer, true); + ArraySetAsSeries(smLowBuffer, true); + ArraySetAsSeries(smCloseBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xhk", + // + // Inputs ... + // + // Market ... + "", + mInputs.smoothingLength, // Smoothing Length + // + // Presentation ... + "", + mInputs.drawHikenAshi, // Draw Hiken Ashi + mInputs.drawSmoothedHikenAshi // Draw Smoothed Hiken Ashi + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XHKInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XHKInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(openBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return openBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyOpen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + openBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(highBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return highBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHigh( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + highBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(closeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return closeBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyClose( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + closeBuffer, + buffer, + forceClean + // + ); + } + + // + // Smoothed ... + + // + double GetSMOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(smOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return smOpenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySMOpen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + smOpenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSMHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(smHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return smHighBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySMHigh( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + smHighBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSMLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(smLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return smLowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySMLow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + smLowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSMClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(smCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return smCloseBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySMClose( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + smCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // XOHCL ... + + // + // Retrieve Hiken Ashi Info as XOHCL model ... + bool AsOHCL( + XOHCL &bar, // Holds Result + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(openBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + double open = GetOpen(barIndex); + double high = GetHigh(barIndex); + double close = GetClose(barIndex); + double low = GetLow(barIndex); + + // + result = bar.Init( + mSymbol, + mPeriod, + open, + high, + close, + low, + barIndex + // + ); + + // + return result; + } + + // + // Copy Required Items ... + int CopyAsOHCL( + int start, // Start + int count, // Number of Items for read + XOHCL &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + int result = 0; + + // + // Update Calculations ... + Calculate(); + + // + if (forceClean) + { + Clean(buffer); + } + + // + int before = ArraySize(buffer); + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(openBuffer)) + { + start = ArraySize(openBuffer) - 1; + } + + // + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); + + // + for (int i = start; i < start + count; i++) + { + // + XOHCL iBar; + bool isInit = AsOHCL(iBar, i); + + // + if (isInit) + { + // + AddRef( + iBar, + buffer + // + ); + } + } + + // + ArraySetAsSeries(buffer, asSeriesBuffer); + + // + int after = ArraySize(buffer); + + // + result = after - before; + + // + return result; + } + + // + // Retrieve Smoothed Hiken Ashi Info as XOHCL model ... + bool SMAsOHCL( + XOHCL &bar, // Holds Result + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(openBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + double open = GetSMOpen(barIndex); + double high = GetSMHigh(barIndex); + double close = GetSMClose(barIndex); + double low = GetSMLow(barIndex); + + // + result = bar.Init( + mSymbol, + mPeriod, + open, + high, + close, + low, + barIndex + // + ); + + // + return result; + } + + // + // Copy Required Items ... + int CopySMAsOHCL( + int start, // Start + int count, // Number of Items for read + XOHCL &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + int result = 0; + + // + // Update Calculations ... + Calculate(); + + // + if (forceClean) + { + Clean(buffer); + } + + // + int before = ArraySize(buffer); + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(openBuffer)) + { + start = ArraySize(openBuffer) - 1; + } + + // + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); + + // + for (int i = start; i < start + count; i++) + { + // + XOHCL iBar; + bool isInit = SMAsOHCL(iBar, i); + + // + if (isInit) + { + // + AddRef( + iBar, + buffer + // + ); + } + } + + // + ArraySetAsSeries(buffer, asSeriesBuffer); + + // + int after = ArraySize(buffer); + + // + result = after - before; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XHKInputs mInputs; // Inputs ... + + // + // Buffers ... + double openBuffer[]; + double highBuffer[]; + double lowBuffer[]; + double closeBuffer[]; + double smOpenBuffer[]; + double smHighBuffer[]; + double smLowBuffer[]; + double smCloseBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Open Buffer ... + CopyBuffer( + mHandler, + XHK_OPEN_LINE, + 0, + totalBars, + openBuffer + // + ); + + // + // High Buffer ... + CopyBuffer( + mHandler, + XHK_HIGHLINE, + 0, + totalBars, + highBuffer + // + ); + + // + // Low Buffer ... + CopyBuffer( + mHandler, + XHK_LOW_LINE, + 0, + totalBars, + lowBuffer + // + ); + + // + // Close Buffer ... + CopyBuffer( + mHandler, + XHK_CLOSE_LINE, + 0, + totalBars, + closeBuffer + // + ); + + // + // Smoothed ... + + // + // Open Buffer ... + CopyBuffer( + mHandler, + XHK_SM_OPEN_LINE, + 0, + totalBars, + smOpenBuffer + // + ); + + // + // High Buffer ... + CopyBuffer( + mHandler, + XHK_SM_HIGHLINE, + 0, + totalBars, + smHighBuffer + // + ); + + // + // Low Buffer ... + CopyBuffer( + mHandler, + XHK_SM_LOW_LINE, + 0, + totalBars, + smLowBuffer + // + ); + + // + // Close Buffer ... + CopyBuffer( + mHandler, + XHK_SM_CLOSE_LINE, + 0, + totalBars, + smCloseBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhull.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhull.helper.mq5 new file mode 100644 index 0000000..900f629 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xhull.helper.mq5 @@ -0,0 +1,399 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHULLHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XHULLC_BUFFERS +{ + XHULLC_UP_LINE = 0, + XHULLC_DOWN_LINE = 2, +}; + +// +// Input Models ... +struct XHULLInputs +{ + // + // Props ... + // + // Market ... + int length; // Length + double divisor; // Divisor (Speed) + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied to + + // + // Presentation ... + bool showUpZone; // Show Up Zone + bool showDownZone; // Show Down Zone + + // + // Constructor(s) ... + XHULLInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + length = 0; + divisor = 0; + + // + // Calculation ... + upAppliedTo = PRICE_HIGH; + downAppliedTo = PRICE_LOW; + + // + // Presentation ... + showUpZone = false; + showDownZone = false; + } + + // + // Default ... + void Default() + { + // + // Market ... + length = 72; + divisor = 2.0; + + // + // Calculation ... + upAppliedTo = PRICE_HIGH; + downAppliedTo = PRICE_LOW; + + // + // Presentation ... + showUpZone = true; + showDownZone = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 9 && + divisor >= 0.5 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXHULLHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXHULLHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXHULLHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XHULLInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + // ArraySetAsSeries(mainBuffer, true); + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xhull", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, // Length + mInputs.divisor, // Divisor (Speed) + // + // Calculation ... + "", + mInputs.upAppliedTo, // Up Zone Applied to + mInputs.downAppliedTo, // Down Zone Applied to + // + // Presentation ... + "", + mInputs.showUpZone, // Show Up Zone + mInputs.showDownZone // Show Down Zone + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XHULLInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XHULLInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetUp( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(upBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return upBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyUp( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + upBuffer, + buffer, + forceClean + // + ); + } + + // + double GetDown( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(downBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return downBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyDown( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + downBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XHULLInputs mInputs; // Inputs ... + + // + // Buffers ... + double upBuffer[]; + double downBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Up Buffer ... + CopyBuffer( + mHandler, + XHULLC_UP_LINE, + 0, + totalBars, + upBuffer + // + ); + + // + // Down Buffer ... + CopyBuffer( + mHandler, + XHULLC_DOWN_LINE, + 0, + totalBars, + downBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xich.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xich.helper.mq5 new file mode 100644 index 0000000..3a1dcf9 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xich.helper.mq5 @@ -0,0 +1,827 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXICHHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_XICH_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +enum ENUM_XICH_BUFFERS +{ + X_ICH_TEANKANSEN_LINE = 0, + X_ICH_KIJUNSEN_LINE = 1, + X_ICH_CHIKOUSPAN_LINE = 4, + X_ICH_SENKOUSPANA_LINE = 5, + X_ICH_SENKOUSPANB_LINE = 6, +}; + +// +// Input Models ... +struct XICHInputs +{ + // + // Props ... + + // + // Market ... + // + // Tenkan Sen ... + int tenkanSenLength; // Length + ENUM_XICH_CALCULATION_MODE tenkanSenMode; // Calculation Mode + + // + // Kijun Sen ... + int kijunSenLength; // Length + ENUM_XICH_CALCULATION_MODE kijunSenMode; // Calculation Mode + + // + // Senkou Span B ... + int senkouSpanBLength; // Length + ENUM_XICH_CALCULATION_MODE senkouSpanBMode; // Calculation Mode + + // + // Chikou Span ... + ENUM_APPLIED_PRICE chikuoSpanAppliedTo; // Price Type + + // + // Presentation ... + bool showTenkanSen; // Show Tenkan Sen + bool showKijunSen; // Show Kijun Sen + bool showKijunSenPlus; // Show Kijun Sen + + bool showKijunSenNegative; // Show Kijun Sen - + bool showChikouSpan; // Show Chikou Span + bool showSenkouSpanA; // Show Senkou Span A + bool showSenkouSpanB; // Show Senkou Span B + bool showKumo; // Show Kumo + bool shiftKumo; // Shift Kumo to Future + + // + // Constructor(s) ... + XICHInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + kijunSenLength = 0; + tenkanSenLength = 0; + senkouSpanBLength = 0; + + // + kijunSenMode = X_XICH_HH_LL_MODE; + tenkanSenMode = X_XICH_HH_LL_MODE; + senkouSpanBMode = X_XICH_HH_LL_MODE; + + // + chikuoSpanAppliedTo = PRICE_CLOSE; + + // + showTenkanSen = false; + showKijunSen = false; + showKijunSenPlus = false; + showKijunSenNegative = false; + showChikouSpan = false; + showSenkouSpanA = false; + showSenkouSpanB = false; + showKumo = false; + shiftKumo = true; + } + + // + // Default ... + void Default() + { + // + kijunSenLength = 26; + tenkanSenLength = 9; + senkouSpanBLength = 52; + + // + kijunSenMode = X_XICH_HH_LL_MODE; + tenkanSenMode = X_XICH_HH_LL_MODE; + senkouSpanBMode = X_XICH_HH_LL_MODE; + + // + chikuoSpanAppliedTo = PRICE_CLOSE; + + // + showTenkanSen = true; + showKijunSen = true; + showKijunSenPlus = false; + showKijunSenNegative = false; + showChikouSpan = true; + showSenkouSpanA = true; + showSenkouSpanB = true; + showKumo = true; + shiftKumo = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; + } +}; + +// +// Class ... +class XSCXICHHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXICHHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXICHHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XICHInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + ArraySetAsSeries(kijunSenBuffer, true); + ArraySetAsSeries(chikouSpanBuffer, true); + ArraySetAsSeries(senkouSpanABuffer, true); + ArraySetAsSeries(senkouSpanBBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xich", + // + // Inputs ... + // + // TenkanSen ... + "", + mInputs.tenkanSenLength, + mInputs.tenkanSenMode, + // + // KijunSen ... + "", + mInputs.kijunSenLength, + mInputs.kijunSenMode, + // + // SenkouSpan B ... + "", + mInputs.senkouSpanBLength, + mInputs.senkouSpanBMode, + // + // ChikouSpan ... + "", + mInputs.chikuoSpanAppliedTo, + // + // Presentation ... + "", + mInputs.showTenkanSen, // Show Tenkan Sen + mInputs.showKijunSen, // Show Kijun Sen + mInputs.showKijunSenPlus, // Show Kijun Sen + + mInputs.showKijunSenNegative, // Show Kijun Sen - + mInputs.showChikouSpan, // Show Chikou Span + mInputs.showSenkouSpanA, // Show Senkou Span A + mInputs.showSenkouSpanB, // Show Senkou Span B + mInputs.showKumo, // Show Kumo + mInputs.shiftKumo // Shift Kumo to Future + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XICHInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XICHInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs); + } + + // + // Buffers ... + + // + // TenkanSen ... + + // + double GetTenkanSen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return tenkanSenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyTenkanSen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + tenkanSenBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameTenkanSen( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + tenkanSenBuffer, + verifier, + barIndex // + ); + } + + // + // KijunSen ... + + // + double GetKijunSen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return kijunSenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyKijunSen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + kijunSenBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameKijunSen( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + kijunSenBuffer, + verifier, + barIndex // + ); + } + + // + // ChikouSpan ... + + // + double GetChikouSpan( + int barIndex // Bar Index + ) + { + // + barIndex -= mInputs.kijunSenLength; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (barIndex > ArraySize(chikouSpanBuffer)) + { + barIndex = ArraySize(chikouSpanBuffer) - 1; + } + + // + Calculate(); + + // + return chikouSpanBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyChikouSpan( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start - mInputs.kijunSenLength, + count, + chikouSpanBuffer, + buffer, + forceClean + // + ); + } + + // + // SenkouSpanA ... + + // + double GetSenkouSpanA( + int barIndex // Bar Index + ) + { + // + barIndex += mInputs.kijunSenLength; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (barIndex > ArraySize(senkouSpanABuffer)) + { + barIndex = ArraySize(senkouSpanABuffer) - 1; + } + + // + Calculate(); + + // + return senkouSpanABuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySenkouSpanA( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start + mInputs.kijunSenLength, + count, + senkouSpanABuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameSenkouSpanA( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + senkouSpanABuffer, + verifier, + barIndex // + ); + } + + // + // SenkouSpanB ... + + // + double GetSenkouSpanB( + int barIndex // Bar Index + ) + { + // + barIndex += mInputs.kijunSenLength; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (barIndex > ArraySize(senkouSpanBBuffer)) + { + barIndex = ArraySize(senkouSpanBBuffer) - 1; + } + + // + Calculate(); + + // + return senkouSpanBBuffer[barIndex + mInputs.kijunSenLength]; + } + + // + // Copy Required Items ... + int CopySenkouSpanB( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start + mInputs.kijunSenLength, + count, + senkouSpanBBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameSenkouSpanB( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + senkouSpanBBuffer, + verifier, + barIndex // + ); + } + + // + // Future SenkouSpanA ... + + // + double GetFutureSenkouSpanA( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return senkouSpanABuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFutureSenkouSpanA( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + senkouSpanABuffer, + buffer, + forceClean + // + ); + } + + // + // SenkouSpanB ... + + // + double GetFutureSenkouSpanB( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return senkouSpanBBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFutureSenkouSpanB( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + senkouSpanBBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XICHInputs mInputs; // Inputs ... + + // + // Buffers ... + double tenkanSenBuffer[]; + double kijunSenBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + int calculatedBars = CountCalculatedBars(); + + // + // TenkanSen ... + CopyBuffer( + mHandler, + X_ICH_TEANKANSEN_LINE, + 0, + totalBars, + tenkanSenBuffer + // + ); + + // + // KijunSen ... + CopyBuffer( + mHandler, + X_ICH_KIJUNSEN_LINE, + 0, + totalBars, + kijunSenBuffer + // + ); + + // + // ChikouSpan ... + CopyBuffer( + mHandler, + X_ICH_CHIKOUSPAN_LINE, + 0, + totalBars, + chikouSpanBuffer + // + ); + + // + // SenkouSpan A ... + CopyBuffer( + mHandler, + X_ICH_SENKOUSPANA_LINE, + 0, + totalBars, + senkouSpanABuffer + // + ); + + // + // SenkouSpan B ... + CopyBuffer( + mHandler, + X_ICH_SENKOUSPANB_LINE, + 0, + totalBars, + senkouSpanBBuffer + // + ); + } +}; + +// +// Tools ... diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xlh.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xlh.helper.mq5 new file mode 100644 index 0000000..400407a --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xlh.helper.mq5 @@ -0,0 +1,422 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXLHHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XLH_BUFFERS +{ + XLH_HH_LINE = 0, + XLH_LL_LINE = 1, + XLH_SIGNAL_LINE = 2, +}; + +// +// Input Models ... +struct XLHInputs +{ + // + // Props ... + int length; // Length + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Constructor(s) ... + XLHInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + hhMode = MODE_HIGH; + llMode = MODE_LOW; + } + + // + // Default ... + void Default() + { + // + length = 14; + hhMode = MODE_HIGH; + llMode = MODE_LOW; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 2 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXLHHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXLHHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXLHHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XLHInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(hhBuffer, true); + ArraySetAsSeries(llBuffer, true); + ArraySetAsSeries(signalBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xlh", + // + // Inputs ... + mInputs.length, // Length + mInputs.hhMode, // Highest High Calculation Method + mInputs.llMode // Lowest Low Calculation Method + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XLHInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XLHInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hhBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hhBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hhBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(llBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return llBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + llBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(signalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return signalBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + signalBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XLHInputs mInputs; // Inputs ... + + // + // Buffers ... + double hhBuffer[]; + double llBuffer[]; + double signalBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // HH ... + CopyBuffer( + mHandler, + XLH_HH_LINE, + 0, + totalBars, + hhBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XLH_LL_LINE, + 0, + totalBars, + llBuffer + // + ); + + // + // Signal ... + CopyBuffer( + mHandler, + XLH_SIGNAL_LINE, + 0, + totalBars, + signalBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmc.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmc.helper.mq5 new file mode 100644 index 0000000..af386a3 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmc.helper.mq5 @@ -0,0 +1,496 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XMC_BUFFERS +{ + X_MC_FAST_LINE = 0, + X_MC_SLOW_LINE = 1, + X_MC_VERIFIER_LINE = 2, +}; + +// +// Input Models ... +struct XMCInputs +{ + // + // Props ... + + // + // Market ... + + // + // Fast ... + int fastLength; // Length + int fastShift; // Shift + ENUM_MA_METHOD fastMethod; // Method + ENUM_APPLIED_PRICE fastAppliedTo; // Applied To + + // + // Slow ... + int slowLength; // Length + int slowShift; // Shift + ENUM_MA_METHOD slowMethod; // Method + ENUM_APPLIED_PRICE slowAppliedTo; // Applied To + + // + // Verifier ... + int verifierLength; // Length + int verifierShift; // Shift + ENUM_MA_METHOD verifierMethod; // Method + ENUM_APPLIED_PRICE verifierAppliedTo; // Applied To + + // + // Presentation ... + bool showFastMa; // Show Fast + bool showSlowMa; // Show Slow + bool showVerifierMa; // Show Verifier + + // + // Constructor(s) ... + XMCInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + fastLength = 0; + fastShift = 0; + fastMethod = 0; + fastAppliedTo = PRICE_CLOSE; + + // + slowLength = 0; + slowShift = 0; + slowMethod = 0; + slowAppliedTo = PRICE_CLOSE; + + // + verifierLength = 0; + verifierShift = 0; + verifierMethod = 0; + verifierAppliedTo = PRICE_CLOSE; + + // + showFastMa = false; + showSlowMa = false; + showVerifierMa = false; + } + + // + // Default ... + void Default() + { + // + fastLength = 9; + fastShift = 0; + fastMethod = MODE_EMA; + fastAppliedTo = PRICE_CLOSE; + + // + slowLength = 18; + slowShift = 0; + slowMethod = MODE_EMA; + slowAppliedTo = PRICE_CLOSE; + + // + verifierLength = 200; + verifierShift = 0; + verifierMethod = MODE_EMA; + verifierAppliedTo = PRICE_CLOSE; + + // + showFastMa = true; + showSlowMa = true; + showVerifierMa = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + fastLength > 1 && + slowLength > fastLength && + verifierLength > slowLength + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(fastLength, slowLength); + result = MathMax(result, verifierLength); + + // + return result; + } +}; + +// +// Class ... +class XSCXMCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXMCHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXMCHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XMCInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(verifierBuffer, true); + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xmc", + // + // Inputs ... + // + // Fast ... + "", + mInputs.fastLength, + mInputs.fastShift, + mInputs.fastMethod, + mInputs.fastAppliedTo, + // + // Slow ... + "", + mInputs.slowLength, + mInputs.slowShift, + mInputs.slowMethod, + mInputs.slowAppliedTo, + // + // Verifier ... + "", + mInputs.verifierLength, + mInputs.verifierShift, + mInputs.verifierMethod, + mInputs.verifierAppliedTo, + // + // Presentation ... + "", + mInputs.showFastMa, // Show Fast, + mInputs.showSlowMa, // Show Slow, + mInputs.showVerifierMa // Show Verifier + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XMCInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XMCInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs); + } + + // + // Buffers ... + + // + // Fast ... + + // + double GetFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return fastBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return slowBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopySlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowBuffer, + buffer, + forceClean + // + ); + } + + // + // Verifier ... + + // + double GetVerifier( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return verifierBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyVerifier( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + verifierBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XMCInputs mInputs; // Inputs ... + + // + // Buffers ... + // + double fastBuffer[]; + double slowBuffer[]; + double verifierBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Fast ... + CopyBuffer( + mHandler, + X_MC_FAST_LINE, + 0, + totalBars, + fastBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + X_MC_SLOW_LINE, + 0, + totalBars, + slowBuffer + // + ); + + // + // Verifier ... + CopyBuffer( + mHandler, + X_MC_VERIFIER_LINE, + 0, + totalBars, + verifierBuffer + // + ); + } +}; + +// +// Tools ... diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmrb.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmrb.helper.mq5 new file mode 100644 index 0000000..78addb8 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xmrb.helper.mq5 @@ -0,0 +1,1411 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMRBHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XMRB_BUFFERS +{ + // + // Ribbon ... + XMRB_FAST_LINE = 0, + XMRB_SLOW_LINE = 1, + // + // Ribbon 1 ... + XMRB_R1_FAST_LINE = 2, + XMRB_R1_SLOW_LINE = 3, + // + // Ribbon 2 ... + XMRB_R2_FAST_LINE = 4, + XMRB_R2_SLOW_LINE = 5, + // + // Ribbon 3 ... + XMRB_R3_FAST_LINE = 6, + XMRB_R3_SLOW_LINE = 7, + // + // Ribbon 4 ... + XMRB_R4_FAST_LINE = 8, + XMRB_R4_SLOW_LINE = 9, + // + // Ribbon 5 ... + XMRB_R5_FAST_LINE = 10, + XMRB_R5_SLOW_LINE = 11, + // + // Ribbon 5 ... + XMRB_R6_FAST_LINE = 12, + XMRB_R6_SLOW_LINE = 13, +}; + +// +// Input Models ... +struct XMRBInputs +{ + // + // Props ... + + // + // Ribbon 1 ... + int fast1Length; // Fast + int slow1Length; // Slow + ENUM_APPLIED_PRICE r1AppliedTo; // AppliedTo + + // + // Ribbon 2 ... + int fast2Length; // Fast + int slow2Length; // Slow + ENUM_APPLIED_PRICE r2AppliedTo; // AppliedTo + + // + // Ribbon 3 ... + int fast3Length; // Fast + int slow3Length; // Slow + ENUM_APPLIED_PRICE r3AppliedTo; // AppliedTo + + // + // Ribbon 4 ... + int fast4Length; // Fast + int slow4Length; // Slow + ENUM_APPLIED_PRICE r4AppliedTo; // AppliedTo + + // + // Ribbon 5 ... + int fast5Length; // Fast + int slow5Length; // Slow + ENUM_APPLIED_PRICE r5AppliedTo; // AppliedTo + + // + // Ribbon 6 ... + int fast6Length; // Fast + int slow6Length; // Slow + ENUM_APPLIED_PRICE r6AppliedTo; // AppliedTo + + // + // Calculation ... + ENUM_MA_METHOD ribbonMode; // Mode + + // + // Presentation ... + bool showFastMa; // Show Fast + bool showSlowMa; // Show Slow + bool showRibbon; // Show Ribbon + + // + // Constructor(s) ... + XMRBInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Ribbon 1 ... + fast1Length = 0; // Fast + slow1Length = 0; // Slow + r1AppliedTo = PRICE_HIGH; // AppliedTo + + // + // Ribbon 2 ... + fast2Length = 0; // Fast + slow2Length = 0; // Slow + r2AppliedTo = PRICE_OPEN; // AppliedTo + + // + // Ribbon 3 ... + fast3Length = 0; // Fast + slow3Length = 0; // Slow + r3AppliedTo = PRICE_CLOSE; // AppliedTo + + // + // Ribbon 4 ... + fast4Length = 0; // Fast + slow4Length = 0; // Slow + r4AppliedTo = PRICE_MEDIAN; // AppliedTo + + // + // Ribbon 5 ... + fast5Length = 0; // Fast + slow5Length = 0; // Slow + r5AppliedTo = PRICE_TYPICAL; // AppliedTo + + // + // Ribbon 6 ... + fast6Length = 0; // Fast + slow6Length = 0; // Slow + r6AppliedTo = PRICE_LOW; // AppliedTo + + // + // Calculation ... + ribbonMode = MODE_EMA; // Mode + + // + // Presentation ... + showFastMa = false; // Show Fast + showSlowMa = false; // Show Slow + showRibbon = false; // Show Ribbon + } + + // + // Default ... + void Default() + { + // + // Ribbon 1 ... + fast1Length = 20; // Fast + slow1Length = 50; // Slow + r1AppliedTo = PRICE_HIGH; // AppliedTo + + // + // Ribbon 2 ... + fast2Length = 20; // Fast + slow2Length = 50; // Slow + r2AppliedTo = PRICE_OPEN; // AppliedTo + + // + // Ribbon 3 ... + fast3Length = 20; // Fast + slow3Length = 50; // Slow + r3AppliedTo = PRICE_CLOSE; // AppliedTo + + // + // Ribbon 4 ... + fast4Length = 20; // Fast + slow4Length = 50; // Slow + r4AppliedTo = PRICE_MEDIAN; // AppliedTo + + // + // Ribbon 5 ... + fast5Length = 20; // Fast + slow5Length = 50; // Slow + r5AppliedTo = PRICE_TYPICAL; // AppliedTo + + // + // Ribbon 6 ... + fast6Length = 20; // Fast + slow6Length = 50; // Slow + r6AppliedTo = PRICE_LOW; // AppliedTo + + // + // Calculation ... + ribbonMode = MODE_EMA; // Mode + + // + // Presentation ... + showFastMa = true; // Show Fast + showSlowMa = true; // Show Slow + showRibbon = false; // Show Ribbon + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + (fast1Length > 2 && + fast2Length > 2 && + fast3Length > 2 && + fast4Length > 2 && + fast5Length > 2 && + fast6Length > 2 && + slow1Length > fast1Length && + slow2Length > fast2Length && + slow3Length > fast3Length && + slow4Length > fast4Length && + slow5Length > fast5Length && + slow6Length > fast6Length + // + ) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(fast1Length, fast2Length); + result = MathMax(result, fast3Length); + result = MathMax(result, fast4Length); + result = MathMax(result, fast5Length); + result = MathMax(result, fast6Length); + + // + result = MathMax(result, slow1Length); + result = MathMax(result, slow2Length); + result = MathMax(result, slow3Length); + result = MathMax(result, slow4Length); + result = MathMax(result, slow5Length); + result = MathMax(result, slow6Length); + + // + return result; + } +}; + +// +// Class ... +class XSCXMRBHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXMRBHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXMRBHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XMRBInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(r1FastBuffer, true); + ArraySetAsSeries(r1SlowBuffer, true); + ArraySetAsSeries(r2FastBuffer, true); + ArraySetAsSeries(r2SlowBuffer, true); + ArraySetAsSeries(r3FastBuffer, true); + ArraySetAsSeries(r3SlowBuffer, true); + ArraySetAsSeries(r4FastBuffer, true); + ArraySetAsSeries(r4SlowBuffer, true); + ArraySetAsSeries(r5FastBuffer, true); + ArraySetAsSeries(r5SlowBuffer, true); + ArraySetAsSeries(r6FastBuffer, true); + ArraySetAsSeries(r6SlowBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xmrb", + // + // Inputs ... + // + // Ribbon 1 ... + "", + mInputs.fast1Length, // Fast + mInputs.slow1Length, // Slow + mInputs.r1AppliedTo, // AppliedTo + // + // Ribbon 2 ... + "", + mInputs.fast2Length, // Fast + mInputs.slow2Length, // Slow + mInputs.r2AppliedTo, // AppliedTo + // + // Ribbon 3 ... + "", + mInputs.fast3Length, // Fast + mInputs.slow3Length, // Slow + mInputs.r3AppliedTo, // AppliedTo + // + // Ribbon 4 ... + "", + mInputs.fast4Length, // Fast + mInputs.slow4Length, // Slow + mInputs.r4AppliedTo, // AppliedTo + // + // Ribbon 5 ... + "", + mInputs.fast5Length, // Fast + mInputs.slow5Length, // Slow + mInputs.r5AppliedTo, // AppliedTo + // + // Ribbon 6 ... + "", + mInputs.fast6Length, // Fast + mInputs.slow6Length, // Slow + mInputs.r6AppliedTo, // AppliedTo + // + // Calculation ... + "", + mInputs.ribbonMode, // Mode + // + // Presentation ... + "", + mInputs.showFastMa, // Show Fast + mInputs.showSlowMa, // Show Slow + mInputs.showRibbon // Show Ribbon + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XMRBInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XMRBInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Fast ... + + // + double GetFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(slowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowBuffer, + buffer, + forceClean + // + ); + } + + // + // Ribbon 1 ... + + // + // Fast ... + + // + double GetR1Fast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r1FastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r1FastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR1Fast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r1FastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetR1Slow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r1SlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r1SlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR1Slow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r1SlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Ribbon 2 ... + + // + // Fast ... + + // + double GetR2Fast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r2FastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r2FastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR2Fast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r2FastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetR2Slow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r2SlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r2SlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR2Slow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r2SlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Ribbon 3 ... + + // + // Fast ... + + // + double GetR3Fast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r3FastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r3FastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR3Fast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r3FastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetR3Slow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r3SlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r3SlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR3Slow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r3SlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Ribbon 4 ... + + // + // Fast ... + + // + double GetR4Fast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r4FastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r4FastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR4Fast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r4FastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetR4Slow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r4SlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r4SlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR4Slow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r4SlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Ribbon 5 ... + + // + // Fast ... + + // + double GetR5Fast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r5FastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r5FastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR5Fast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r5FastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetR5Slow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r5SlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r5SlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR5Slow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r5SlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Ribbon 6 ... + + // + // Fast ... + + // + double GetR6Fast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r6FastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r6FastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR6Fast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r6FastBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow ... + + // + double GetR6Slow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(r6SlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return r6SlowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyR6Slow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + r6SlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XMRBInputs mInputs; // Inputs ... + + // + // Buffers ... + double fastBuffer[]; + double slowBuffer[]; + double r1FastBuffer[]; + double r1SlowBuffer[]; + double r2FastBuffer[]; + double r2SlowBuffer[]; + double r3FastBuffer[]; + double r3SlowBuffer[]; + double r4FastBuffer[]; + double r4SlowBuffer[]; + double r5FastBuffer[]; + double r5SlowBuffer[]; + double r6FastBuffer[]; + double r6SlowBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Fast Buffer ... + CopyBuffer( + mHandler, + XMRB_FAST_LINE, + 0, + totalBars, + fastBuffer + // + ); + + // + // Slow Buffer ... + CopyBuffer( + mHandler, + XMRB_SLOW_LINE, + 0, + totalBars, + slowBuffer + // + ); + + // + // Ribbon 1 ... + + // + // Fast Buffer ... + CopyBuffer( + mHandler, + XMRB_R1_FAST_LINE, + 0, + totalBars, + r1FastBuffer + // + ); + + // + // Slow Buffer ... + CopyBuffer( + mHandler, + XMRB_R1_SLOW_LINE, + 0, + totalBars, + r1SlowBuffer + // + ); + + // + // Ribbon 2 ... + + // + // Fast Buffer ... + CopyBuffer( + mHandler, + XMRB_R2_FAST_LINE, + 0, + totalBars, + r2FastBuffer + // + ); + + // + // Slow Buffer ... + CopyBuffer( + mHandler, + XMRB_R2_SLOW_LINE, + 0, + totalBars, + r2SlowBuffer + // + ); + + // + // Ribbon 3 ... + + // + // Fast Buffer ... + CopyBuffer( + mHandler, + XMRB_R3_FAST_LINE, + 0, + totalBars, + r3FastBuffer + // + ); + + // + // Slow Buffer ... + CopyBuffer( + mHandler, + XMRB_R3_SLOW_LINE, + 0, + totalBars, + r3SlowBuffer + // + ); + + // + // Ribbon 4 ... + + // + // Fast Buffer ... + CopyBuffer( + mHandler, + XMRB_R4_FAST_LINE, + 0, + totalBars, + r4FastBuffer + // + ); + + // + // Slow Buffer ... + CopyBuffer( + mHandler, + XMRB_R4_SLOW_LINE, + 0, + totalBars, + r4SlowBuffer + // + ); + + // + // Ribbon 5 ... + + // + // Fast Buffer ... + CopyBuffer( + mHandler, + XMRB_R5_FAST_LINE, + 0, + totalBars, + r5FastBuffer + // + ); + + // + // Slow Buffer ... + CopyBuffer( + mHandler, + XMRB_R5_SLOW_LINE, + 0, + totalBars, + r5SlowBuffer + // + ); + + // + // Ribbon 6 ... + + // + // Fast Buffer ... + CopyBuffer( + mHandler, + XMRB_R6_FAST_LINE, + 0, + totalBars, + r6FastBuffer + // + ); + + // + // Slow Buffer ... + CopyBuffer( + mHandler, + XMRB_R6_SLOW_LINE, + 0, + totalBars, + r6SlowBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xobd.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xobd.helper.mq5 new file mode 100644 index 0000000..03957cb --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xobd.helper.mq5 @@ -0,0 +1,306 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXOBDHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XOBD_BUFFERS +{ + XOBD_MAIN_LINE = 0 +}; + +// +// Input Models ... +struct XOBDInputs +{ + // + // Props ... + + // + int length; // Swing Length + + // + uchar swingHighArrowCode; // Swing High Arrow Code + color swingHighArrowColor; // Swing High Arrow Color + + // + uchar swingLowArrowCode; // Swing Low Arrow Code + color swingLowArrowColor; // Swing Low Arrow Color + + // + // Constructor(s) ... + XOBDInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + swingHighArrowCode = 0; + swingHighArrowColor = CLR_NONE; + swingLowArrowCode = 0; + swingLowArrowColor = CLR_NONE; + } + + // + // Default ... + void Default() + { + // + length = 5; + swingHighArrowCode = 0; + swingHighArrowColor = CLR_NONE; + swingLowArrowCode = 0; + swingLowArrowColor = CLR_NONE; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 3 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXOBDHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXOBDHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXOBDHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XOBDInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(mainBuffer, true); + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xobd", + // + // Inputs ... + mInputs.length, // Swing Length + mInputs.swingHighArrowCode, // Swing High Arrow Code + mInputs.swingHighArrowColor, // Swing High Arrow Color + mInputs.swingLowArrowCode, // Swing Low Arrow Code + mInputs.swingLowArrowColor // Swing Low Arrow Color + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XOBDInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XOBDInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetMain( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mainBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mainBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMain( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mainBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XOBDInputs mInputs; // Inputs ... + + // + // Buffers ... + double mainBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Main ... + CopyBuffer( + mHandler, + XOBD_MAIN_LINE, + 0, + totalBars, + mainBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xosc.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xosc.helper.mq5 new file mode 100644 index 0000000..20f738e --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xosc.helper.mq5 @@ -0,0 +1,1321 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXOSCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XOSC_BUFFERS +{ + X_OSC_ATR_LINE = 0, + X_OSC_RVI_MAIN_LINE = 1, + X_OSC_RVI_SIGNAL_LINE = 2, + X_OSC_BULL_POWER_LINE = 3, + X_OSC_BEAR_POWER_LINE = 4, + X_OSC_VOLUME_LINE = 5, + X_OSC_RSI_LINE = 6, + X_OSC_CCI_LINE = 7, + X_OSC_MOMENTUM_LINE = 8, + X_OSC_SAR_LINE = 9, + X_OSC_MACD_MAIN_LINE = 10, + X_OSC_MACD_SIGNAL_LINE = 11, + X_OSC_STOCH_MAIN_LINE = 12, + X_OSC_STOCH_SIGNAL_LINE = 13, + X_OSC_STDDEV_LINE = 14, +}; + +// +// Input Models ... +struct XOSCInputs +{ + // + // Props ... + + // + // ATR ... + int atrLength; // Length + + // + // RVI ... + int rviLength; // Length + + // + // BULLPOWER ... + int bullpLength; // Length + + // + // BEARPOWER ... + int bearpLength; // Length + + // + // VOLUME ... + ENUM_APPLIED_VOLUME volumeAppliedTo; // Applied To + + // + // RSI ... + int rsiLength; // Length + ENUM_APPLIED_PRICE rsiAppliedTo; // Applied To + + // + // CCI ... + int cciLength; // Length + ENUM_APPLIED_PRICE cciAppliedTo; // Applied To + + // + // STDDEV ... + int stddevLength; // Length + int stddevShift; // Shift + ENUM_MA_METHOD stddevMethod; // Mode + ENUM_APPLIED_PRICE stddevAppliedTo; // AppliedTo + + // + // MOMENTUM ... + int momentumLength; // Length + ENUM_APPLIED_PRICE momentumAppliedTo; // Applied To + + // + // SAR ... + double sarStep; // Step + double sarMaximum; // Maximum + + // + // MACD ... + int macdFastLength; // Fast Length + int macdSlowLength; // Slow Length + int macdSignaLength; // Signal Length + ENUM_APPLIED_PRICE macdAppliedTo; // Applied To + + // + // STOCHASTIC ... + // The buffer numbers: 0 - MAIN_LINE, 1 - SIGNAL_LINE. + int stochKLength; // K Length + int stochDLength; // D Length + int stochSlowing; // Slowing + ENUM_MA_METHOD stochMaMethod; // Ma Method + ENUM_STO_PRICE stochMode; // Calculation Mode + + // + // Constructor(s) ... + XOSCInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + atrLength = 0; // Length + rviLength = 0; // Length + bullpLength = 0; // Length + bearpLength = 0; // Length + volumeAppliedTo = VOLUME_TICK; // Applied To + rsiLength = 0; // Length + rsiAppliedTo = PRICE_CLOSE; // Applied To + cciLength = 0; // Length + cciAppliedTo = PRICE_TYPICAL; // Applied To + stddevLength = 0; // Length + stddevShift = 0; // Shift + stddevMethod = MODE_SMA; // Mode + stddevAppliedTo = PRICE_CLOSE; // AppliedTo + momentumLength = 0; // Length + momentumAppliedTo = PRICE_CLOSE; // Applied To + sarStep = 0; // Step + sarMaximum = 0; // Maximum + macdFastLength = 0; // Fast Length + macdSlowLength = 0; // Slow Length + macdSignaLength = 0; // Signal Length + macdAppliedTo = PRICE_CLOSE; // Applied To + stochKLength = 0; // K Length + stochDLength = 0; // D Length + stochSlowing = 0; // Slowing + stochMaMethod = MODE_SMA; // Ma Method + stochMode = STO_LOWHIGH; // Calculation Mode + } + + // + // Default ... + void Default() + { + // + atrLength = 14; // Length + rviLength = 10; // Length + bullpLength = 13; // Length + bearpLength = 13; // Length + volumeAppliedTo = VOLUME_TICK; // Applied To + rsiLength = 14; // Length + rsiAppliedTo = PRICE_CLOSE; // Applied To + cciLength = 14; // Length + cciAppliedTo = PRICE_TYPICAL; // Applied To + stddevLength = 20; // Length + stddevShift = 0; // Shift + stddevMethod = MODE_SMA; // Mode + stddevAppliedTo = PRICE_CLOSE; // AppliedTo + momentumLength = 14; // Length + momentumAppliedTo = PRICE_CLOSE; // Applied To + sarStep = 0.02; // Step + sarMaximum = 0.2; // Maximum + macdFastLength = 12; // Fast Length + macdSlowLength = 26; // Slow Length + macdSignaLength = 9; // Signal Length + macdAppliedTo = PRICE_CLOSE; // Applied To + stochKLength = 5; // K Length + stochDLength = 3; // D Length + stochSlowing = 3; // Slowing + stochMaMethod = MODE_SMA; // Ma Method + stochMode = STO_LOWHIGH; // Calculation Mode + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + atrLength >= 2 && + rviLength >= 2 && + bullpLength >= 2 && + bearpLength >= 2 && + rsiLength >= 2 && + cciLength >= 2 && + momentumLength >= 2 && + sarStep > 0 && + sarStep < sarMaximum && + macdFastLength >= 2 && + macdSlowLength > macdFastLength && + macdSignaLength >= 2 && + stochKLength >= 2 && + stochDLength >= 2 && + stochSlowing >= 2 && + stddevLength >= 2 && + stddevShift >= 0 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(atrLength, rviLength); + result = MathMax(result, bullpLength); + result = MathMax(result, bearpLength); + result = MathMax(result, rsiLength); + result = MathMax(result, cciLength); + result = MathMax(result, momentumLength); + result = MathMax(result, macdFastLength); + result = MathMax(result, macdSlowLength); + result = MathMax(result, macdSignaLength); + result = MathMax(result, stochKLength); + result = MathMax(result, stochDLength); + result = MathMax(result, stochSlowing); + result = MathMax(result, stddevLength); + + // + return result; + } +}; + +// +// Class ... +class XSCXOSCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXOSCHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXOSCHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XOSCInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(atrBuffer, true); + ArraySetAsSeries(rviMainBuffer, true); + ArraySetAsSeries(rviSignalBuffer, true); + ArraySetAsSeries(bullPBuffer, true); + ArraySetAsSeries(bearPBuffer, true); + ArraySetAsSeries(volumeBuffer, true); + ArraySetAsSeries(rsiBuffer, true); + ArraySetAsSeries(cciBuffer, true); + ArraySetAsSeries(momentumBuffer, true); + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(macdMainBuffer, true); + ArraySetAsSeries(macdSignalBuffer, true); + ArraySetAsSeries(stochMainBuffer, true); + ArraySetAsSeries(stochSignalBuffer, true); + ArraySetAsSeries(stddevBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xosc", + // + // Inputs ... + // + // ATR ... + "", + mInputs.atrLength, + // + // RVI ... + "", + mInputs.rviLength, + // + // Bulls Power ... + "", + mInputs.bullpLength, + // + // Bears Power ... + "", + mInputs.bearpLength, + // + // Voluem ... + "", + mInputs.volumeAppliedTo, + // + // RSI ... + "", + mInputs.rsiLength, + mInputs.rsiAppliedTo, + // + // CCI ... + "", + mInputs.cciLength, + mInputs.cciAppliedTo, + // + // STDDev ... + "", + mInputs.stddevLength, + mInputs.stddevShift, + mInputs.stddevMethod, + mInputs.stddevAppliedTo, + // + // Momentum ... + "", + mInputs.momentumLength, + mInputs.momentumAppliedTo, + // + // SAR ... + "", + mInputs.sarStep, + mInputs.sarMaximum, + // + // MACD ... + "", + mInputs.macdFastLength, + mInputs.macdSlowLength, + mInputs.macdSignaLength, + mInputs.macdAppliedTo, + // + // Stochastic ... + "", + mInputs.stochKLength, + mInputs.stochDLength, + mInputs.stochSlowing, + mInputs.stochMaMethod, + mInputs.stochMode + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XOSCInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XOSCInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs); + } + + // + // Buffers ... + + // + // ATR ... + + // + double GetATR( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return atrBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyATR( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + atrBuffer, + buffer, + forceClean + // + ); + } + + // + // RVI ... + + // + double GetRVI( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return rviMainBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyRVI( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + rviMainBuffer, + buffer, + forceClean + // + ); + } + + // + double GetRVISignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return rviSignalBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyRVISignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + rviSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // BULLP ... + + // + double GetBullPower( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return bullPBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyBullPower( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + bullPBuffer, + buffer, + forceClean + // + ); + } + + // + // BEARP ... + + // + double GetBearPower( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return bearPBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyBearPower( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + bearPBuffer, + buffer, + forceClean + // + ); + } + + // + // VOLUME ... + + // + double GetVolume( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return volumeBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyVolume( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + volumeBuffer, + buffer, + forceClean + // + ); + } + + // + // RSI ... + + // + double GetRSI( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return rsiBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyRSI( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + rsiBuffer, + buffer, + forceClean + // + ); + } + + // + // CCI ... + + // + double GetCCI( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return cciBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyCCI( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + cciBuffer, + buffer, + forceClean + // + ); + } + + // + // MOMENTUM ... + + // + double GetMomentum( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return momentumBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyMomentum( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + momentumBuffer, + buffer, + forceClean + // + ); + } + + // + // SAR ... + + // + double GetSAR( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return sarBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopySAR( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + sarBuffer, + buffer, + forceClean + // + ); + } + + // + // STDDEV ... + + // + double GetSTDDEV( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return stddevBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopySTDDEV( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + stddevBuffer, + buffer, + forceClean + // + ); + } + + // + // MACD ... + + // + double GetMACD( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return macdMainBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyMACD( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + macdMainBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMACDSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return macdSignalBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyMACDSignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + macdSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // STOCH ... + + // + double GetSTOCH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return stochMainBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopySTOCH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + stochMainBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTOCHSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return stochSignalBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopySTOCHSignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + stochSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XOSCInputs mInputs; // Inputs ... + + // + // Buffers ... + double atrBuffer[]; + double rviMainBuffer[]; + double rviSignalBuffer[]; + double bullPBuffer[]; + double bearPBuffer[]; + double volumeBuffer[]; + double rsiBuffer[]; + double cciBuffer[]; + double momentumBuffer[]; + double sarBuffer[]; + double macdMainBuffer[]; + double macdSignalBuffer[]; + double stochMainBuffer[]; + double stochSignalBuffer[]; + double stddevBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + int calculatedBars = CountCalculatedBars(); + + // + // ATR ... + CopyBuffer( + mHandler, + X_OSC_ATR_LINE, + 0, + totalBars, + atrBuffer + // + ); + + // + // BULLP ... + CopyBuffer( + mHandler, + X_OSC_BULL_POWER_LINE, + 0, + totalBars, + bullPBuffer + // + ); + + // + // BEARP ... + CopyBuffer( + mHandler, + X_OSC_BEAR_POWER_LINE, + 0, + totalBars, + bearPBuffer + // + ); + + // + // VOLUME ... + CopyBuffer( + mHandler, + X_OSC_VOLUME_LINE, + 0, + totalBars, + volumeBuffer + // + ); + + // + // RSI ... + CopyBuffer( + mHandler, + X_OSC_RSI_LINE, + 0, + totalBars, + rsiBuffer + // + ); + + // + // CCI ... + CopyBuffer( + mHandler, + X_OSC_CCI_LINE, + 0, + totalBars, + cciBuffer + // + ); + + // + // MOMENTUM ... + CopyBuffer( + mHandler, + X_OSC_MOMENTUM_LINE, + 0, + totalBars, + momentumBuffer + // + ); + + // + // SAR ... + CopyBuffer( + mHandler, + X_OSC_SAR_LINE, + 0, + totalBars, + sarBuffer + // + ); + + // + // STDDEV ... + CopyBuffer( + mHandler, + X_OSC_STDDEV_LINE, + 0, + totalBars, + stddevBuffer + // + ); + + // + // RVI ... + + // + // RVI Main ... + CopyBuffer( + mHandler, + X_OSC_RVI_MAIN_LINE, + 0, + totalBars, + rviMainBuffer + // + ); + + // + // RVI Signal ... + CopyBuffer( + mHandler, + X_OSC_RVI_SIGNAL_LINE, + 0, + totalBars, + rviSignalBuffer + // + ); + + // + // MACD ... + + // + // MACD Main ... + CopyBuffer( + mHandler, + X_OSC_MACD_MAIN_LINE, + 0, + totalBars, + macdMainBuffer + // + ); + + // + // MACD Signal ... + CopyBuffer( + mHandler, + X_OSC_MACD_SIGNAL_LINE, + 0, + totalBars, + macdSignalBuffer + // + ); + + // + // STOCH ... + + // + // STOCH Main ... + CopyBuffer( + mHandler, + X_OSC_STOCH_MAIN_LINE, + 0, + totalBars, + stochMainBuffer + // + ); + + // + // STOCH Signal ... + CopyBuffer( + mHandler, + X_OSC_STOCH_SIGNAL_LINE, + 0, + totalBars, + stochSignalBuffer + // + ); + } +}; + +// +// Tools ... diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xpv.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xpv.helper.mq5 new file mode 100644 index 0000000..b78b183 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xpv.helper.mq5 @@ -0,0 +1,1870 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXPVHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XPV_BUFFERS +{ + // + // Peaks and Vales ... + XPV_PEAKS_LINE = 0, + XPV_VALES_LINE = 1, + // + // Support and Resistances ... + XPV_RESISTANCE_LINE = 2, + XPV_SUPPORT_LINE = 4, + // + // Fibonacci ... + XPV_FIB_1_LINE = 6, + XPV_FIB_2_LINE = 8, + XPV_FIB_3_LINE = 10, + XPV_FIB_4_LINE = 12, + XPV_FIB_5_LINE = 14, + // + // Short ... + XPV_SC_HH_LINE = 16, + XPV_SC_LL_LINE = 18, + // + // Medium ... + XPV_MC_HH_LINE = 20, + XPV_MC_LL_LINE = 22, + // + // Long ... + XPV_LC_HH_LINE = 24, + XPV_LC_LL_LINE = 26, + // + // Hind ... + XPV_HC_HH_LINE = 28, + XPV_HC_LL_LINE = 30, +}; + +// +// Input Models ... +struct XPVInputs +{ + // + // Props ... + + // + // Makret Cycles ... + + // + // Short ... + ENUM_X_PERIOD_METHOD scMethod; // How to Find Period + ENUM_TIMEFRAMES scPeriod; // Time Period + + // + // Medium ... + ENUM_X_PERIOD_METHOD mcMethod; // How to Find Period + ENUM_TIMEFRAMES mcPeriod; // Time Period + + // + // Long ... + ENUM_X_PERIOD_METHOD lcMethod; // How to Find Period + ENUM_TIMEFRAMES lcPeriod; // Time Period + + // + // Hind ... + ENUM_X_PERIOD_METHOD hcMethod; // How to Find Period + ENUM_TIMEFRAMES hcPeriod; // Time Period + + // + // Fibonacci ... + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + double fiboLevel4; // Fibio 4th Level + double fiboLevel5; // Fibio 5th Level + + // + // Boundary Detection Modes ... + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Presentation ... + bool showPeaksAndVales; // Show Peaks and Vales + bool showLevels; // Show Levels + bool showConsolidations; // Show Consolidations + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level + bool showFibo4Levels; // Show Fibo 4th Level + bool showFibo5Levels; // Show Fibo 5th Level + + // + // Constructor(s) ... + XPVInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Makret Cycles ... + + // + // Short ... + scMethod = X_PERIOD_NOTHING; + scPeriod = NULL; + + // + // Medium ... + mcMethod = X_PERIOD_NOTHING; + mcPeriod = NULL; + + // + // Long ... + lcMethod = X_PERIOD_NOTHING; + lcPeriod = NULL; + + // + // Hind ... + hcMethod = X_PERIOD_NOTHING; + hcPeriod = NULL; + + // + // Fibonacci ... + fiboLevel1 = 0; + fiboLevel2 = 0; + fiboLevel3 = 0; + fiboLevel4 = 0; + fiboLevel5 = 0; + + // + // Boundary Detection Modes ... + hhMode = MODE_HIGH; + llMode = MODE_LOW; + + // + // Presentation ... + showPeaksAndVales = false; + showLevels = false; + showConsolidations = false; + showFibo1Levels = false; + showFibo2Levels = false; + showFibo3Levels = false; + showFibo4Levels = false; + showFibo5Levels = false; + } + + // + // Default ... + void Default() + { + // + // Makret Cycles ... + + // + // Short ... + scMethod = X_PERIOD_AUTO; + scPeriod = NULL; + + // + // Medium ... + mcMethod = X_PERIOD_AUTO; + mcPeriod = NULL; + + // + // Long ... + lcMethod = X_PERIOD_AUTO; + lcPeriod = NULL; + + // + // Hind ... + hcMethod = X_PERIOD_AUTO; + hcPeriod = NULL; + + // + // Fibonacci ... + fiboLevel1 = 0.236; + fiboLevel2 = 0.382; + fiboLevel3 = 0.5; + fiboLevel4 = 0.618; + fiboLevel5 = 0.764; + + // + // Boundary Detection Modes ... + hhMode = MODE_HIGH; + llMode = MODE_LOW; + + // + // Presentation ... + showPeaksAndVales = true; + showLevels = false; + showConsolidations = false; + showFibo1Levels = true; + showFibo2Levels = true; + showFibo3Levels = true; + showFibo4Levels = true; + showFibo5Levels = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, 0); + + // + return result; + } +}; + +// +// Class ... +class XSCXPVHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXPVHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXPVHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XPVInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(peaksBuffer, true); + ArraySetAsSeries(valesBuffer, true); + ArraySetAsSeries(resistanceBuffer, true); + ArraySetAsSeries(supportBuffer, true); + ArraySetAsSeries(fib1Buffer, true); + ArraySetAsSeries(fib2Buffer, true); + ArraySetAsSeries(fib3Buffer, true); + ArraySetAsSeries(fib4Buffer, true); + ArraySetAsSeries(fib5Buffer, true); + ArraySetAsSeries(scHHBuffer, true); + ArraySetAsSeries(scLLBuffer, true); + ArraySetAsSeries(mcHHBuffer, true); + ArraySetAsSeries(mcLLBuffer, true); + ArraySetAsSeries(lcHHBuffer, true); + ArraySetAsSeries(lcLLBuffer, true); + ArraySetAsSeries(hcHHBuffer, true); + ArraySetAsSeries(hcLLBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xpv", + // + // Inputs ... + // + // Makret Cycles ... + "", + // + // Short ... + "", + mInputs.scMethod, // How to Find Period + mInputs.scPeriod, // Time Period + // + // Medium ... + "", + mInputs.mcMethod, // How to Find Period + mInputs.mcPeriod, // Time Period + // + // Long ... + "", + mInputs.lcMethod, // How to Find Period + mInputs.lcPeriod, // Time Period + // + // Hind ... + "", + mInputs.hcMethod, // How to Find Period + mInputs.hcPeriod, // Time Period + // + // Fibonacci ... + "", + mInputs.fiboLevel1, // Fibio 1st Level + mInputs.fiboLevel2, // Fibio 2st Level + mInputs.fiboLevel3, // Fibio 3rd Level + mInputs.fiboLevel4, // Fibio 4th Level + mInputs.fiboLevel5, // Fibio 5th Level + // + // Boundary Detection Modes ... + "", + mInputs.hhMode, // Highest High Calculation Method + mInputs.llMode, // Lowest Low Calculation Method + // + // Presentation ... + "", + mInputs.showPeaksAndVales, // Show Peaks and Vales + mInputs.showLevels, // Show Levels + mInputs.showConsolidations, // Show Consolidations + mInputs.showFibo1Levels, // Show Fibo 1st Level + mInputs.showFibo2Levels, // Show Fibo 2nd Level + mInputs.showFibo3Levels, // Show Fibo 3rd Level + mInputs.showFibo4Levels, // Show Fibo 4th Level + mInputs.showFibo5Levels // Show Fibo 5th Level + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XPVInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XPVInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Peaks ... + + // + double GetPeak( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(peaksBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return peaksBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyPeak( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + peaksBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSamePeak( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + peaksBuffer, + verifier, + barIndex // + ); + } + + // + // Vales ... + + // + double GetVale( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(valesBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return valesBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyVale( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + valesBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameVale( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + valesBuffer, + verifier, + barIndex // + ); + } + + // + // Resistance ... + + // + double GetResistance( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(resistanceBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return resistanceBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyResistance( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + resistanceBuffer, + buffer, + forceClean + // + ); + } + + // + // Support ... + + // + double GetSupport( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(supportBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return supportBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySupport( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + supportBuffer, + buffer, + forceClean + // + ); + } + + // + // Fibonacci ... + + // + // Level 1 ... + + // + double GetFib1( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fib1Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fib1Buffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFib1( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fib1Buffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameFib1( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + fib1Buffer, + verifier, + barIndex // + ); + } + + // + // Level 2 ... + + // + double GetFib2( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fib2Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fib2Buffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFib2( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fib2Buffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameFib2( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + fib2Buffer, + verifier, + barIndex // + ); + } + + // + // Level 3 ... + + // + double GetFib3( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fib3Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fib3Buffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFib3( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fib3Buffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameFib3( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + fib3Buffer, + verifier, + barIndex // + ); + } + + // + // Level 4 ... + + // + double GetFib4( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fib4Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fib4Buffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFib4( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fib4Buffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameFib4( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + fib4Buffer, + verifier, + barIndex // + ); + } + + // + // Level 5 ... + + // + double GetFib5( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fib5Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fib5Buffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFib5( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fib5Buffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameFib5( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + fib5Buffer, + verifier, + barIndex // + ); + } + + // + // Cycles ... + + // + // Short ... + + // + // HH ... + + // + double GetSCHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(scHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return scHHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySCHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + scHHBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameSCHH( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + scHHBuffer, + verifier, + barIndex // + ); + } + + // + // LL ... + + // + double GetSCLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(scLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return scLLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySCLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + scLLBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameSCLL( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + scLLBuffer, + verifier, + barIndex // + ); + } + + // + // Medium ... + + // + // HH ... + + // + double GetMCHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mcHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mcHHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMCHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mcHHBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameMCHH( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + mcHHBuffer, + verifier, + barIndex // + ); + } + + // + // LL ... + + // + double GetMCLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mcLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mcLLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMCLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mcLLBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameMCLL( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + mcLLBuffer, + verifier, + barIndex // + ); + } + + // + // Long ... + + // + // HH ... + + // + double GetLCHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lcHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lcHHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLCHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lcHHBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameLCHH( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + lcHHBuffer, + verifier, + barIndex // + ); + } + + // + // LL ... + + // + double GetLCLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lcLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lcLLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLCLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lcLLBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameLCLL( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + lcLLBuffer, + verifier, + barIndex // + ); + } + + // + // Hind ... + + // + // HH ... + + // + double GetHCHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hcHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hcHHBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHCHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hcHHBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameHCHH( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + hcHHBuffer, + verifier, + barIndex // + ); + } + + // + // LL ... + + // + double GetHCLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hcLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hcLLBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHCLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hcLLBuffer, + buffer, + forceClean + // + ); + } + + // + bool IsSameHCLL( + int barIndex, // Start Bar Index + int verifier = 71 // Number of Verifiers + ) + { + // + // Update Calculations ... + Calculate(); + + // + return IsSame( + hcLLBuffer, + verifier, + barIndex // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XPVInputs mInputs; // Inputs ... + + // + // Buffers ... + double peaksBuffer[]; + double valesBuffer[]; + double resistanceBuffer[]; + double supportBuffer[]; + double fib1Buffer[]; + double fib2Buffer[]; + double fib3Buffer[]; + double fib4Buffer[]; + double fib5Buffer[]; + double scHHBuffer[]; + double scLLBuffer[]; + double mcHHBuffer[]; + double mcLLBuffer[]; + double lcHHBuffer[]; + double lcLLBuffer[]; + double hcHHBuffer[]; + double hcLLBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Peaks and Vales ... + + // + // Peaks Buffer ... + CopyBuffer( + mHandler, + XPV_PEAKS_LINE, + 0, + totalBars, + peaksBuffer + // + ); + + // + // Vales Buffer ... + CopyBuffer( + mHandler, + XPV_VALES_LINE, + 0, + totalBars, + valesBuffer + // + ); + + // + // Support and Resistances ... + + // + // Resistances Buffer ... + CopyBuffer( + mHandler, + XPV_RESISTANCE_LINE, + 0, + totalBars, + resistanceBuffer + // + ); + + // + // Supports Buffer ... + CopyBuffer( + mHandler, + XPV_SUPPORT_LINE, + 0, + totalBars, + supportBuffer + // + ); + + // + // Fibonacci ... + + // + // Level 1 Buffer ... + CopyBuffer( + mHandler, + XPV_FIB_1_LINE, + 0, + totalBars, + fib1Buffer + // + ); + + // + // Level 2 Buffer ... + CopyBuffer( + mHandler, + XPV_FIB_2_LINE, + 0, + totalBars, + fib2Buffer + // + ); + + // + // Level 3 Buffer ... + CopyBuffer( + mHandler, + XPV_FIB_3_LINE, + 0, + totalBars, + fib3Buffer + // + ); + + // + // Level 4 Buffer ... + CopyBuffer( + mHandler, + XPV_FIB_4_LINE, + 0, + totalBars, + fib4Buffer + // + ); + + // + // Level 5 Buffer ... + CopyBuffer( + mHandler, + XPV_FIB_5_LINE, + 0, + totalBars, + fib5Buffer + // + ); + + // + // Cycles ... + + // + // Short ... + + // + // HH ... + CopyBuffer( + mHandler, + XPV_SC_HH_LINE, + 0, + totalBars, + scHHBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XPV_SC_LL_LINE, + 0, + totalBars, + scLLBuffer + // + ); + + // + // Medium ... + + // + // HH ... + CopyBuffer( + mHandler, + XPV_MC_HH_LINE, + 0, + totalBars, + mcHHBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XPV_MC_LL_LINE, + 0, + totalBars, + mcLLBuffer + // + ); + + // + // Long ... + + // + // HH ... + CopyBuffer( + mHandler, + XPV_LC_HH_LINE, + 0, + totalBars, + lcHHBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XPV_LC_LL_LINE, + 0, + totalBars, + lcLLBuffer + // + ); + + // + // Hind ... + + // + // HH ... + CopyBuffer( + mHandler, + XPV_HC_HH_LINE, + 0, + totalBars, + hcHHBuffer + // + ); + + // + // LL ... + CopyBuffer( + mHandler, + XPV_HC_LL_LINE, + 0, + totalBars, + hcLLBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xrsi.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xrsi.helper.mq5 new file mode 100644 index 0000000..804cf35 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xrsi.helper.mq5 @@ -0,0 +1,392 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXRSIHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XRSI_BUFFERS +{ + XRSI_MAIN_LINE = 0 +}; + +// +// Input Models ... +struct XRSIInputs +{ + // + // Props ... + + // + // Market ... + int length; // Market Length + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Short Entry ... + double shortEntryValue; // Short Entry Level + color shortEntryColor; // Short Entry Level Color + ENUM_LINE_STYLE shortEntryLineStyle; // Short Entry Style + + // + // Short Exit ... + double shortExitValue; // Short Exit Level + color shortExitColor; // Short Exit Level Color + ENUM_LINE_STYLE shortExitLineStyle; // Short Exit Style + + // + // Long Entry ... + double longEntryValue; // Long Entry Level + color longEntryColor; // Long Entry Level Color + ENUM_LINE_STYLE longEntryLineStyle; // Long Entry Style + + // + // Long Exit ... + double longExitValue; // Long Exit Level + color longExitColor; // Long Exit Level Color + ENUM_LINE_STYLE longExitLineStyle; // Long Exit Style + + // + // Constructor(s) ... + XRSIInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + length = 0; + appliedTo = PRICE_CLOSE; + + // + // Short Entry ... + shortEntryValue = 0; + shortEntryColor = CLR_NONE; + shortEntryLineStyle = STYLE_DOT; + + // + // Short Exit ... + shortExitValue = 0; + shortExitColor = CLR_NONE; + shortExitLineStyle = STYLE_DOT; + + // + // Long Entry ... + longEntryValue = 0; + longEntryColor = CLR_NONE; + longEntryLineStyle = STYLE_DOT; + + // + // Long Exit ... + longExitValue = 0; + longExitColor = CLR_NONE; + longExitLineStyle = STYLE_DOT; + } + + // + // Default ... + void Default() + { + // + // Market ... + length = 14; + appliedTo = PRICE_CLOSE; + + // + // Short Entry ... + shortEntryValue = 70; + shortEntryColor = CLR_NONE; + shortEntryLineStyle = STYLE_DOT; + + // + // Short Exit ... + shortExitValue = 40; + shortExitColor = CLR_NONE; + shortExitLineStyle = STYLE_DOT; + + // + // Long Entry ... + longEntryValue = 30; + longEntryColor = CLR_NONE; + longEntryLineStyle = STYLE_DOT; + + // + // Long Exit ... + longExitValue = 60; + longExitColor = CLR_NONE; + longExitLineStyle = STYLE_DOT; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 2 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXRSIHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXRSIHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXRSIHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XRSIInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(mainBuffer, true); + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xrsi", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, // Market Length + mInputs.appliedTo, // Applied To + // + // Short Entry ... + "", + mInputs.shortEntryValue, // Short Entry Level + mInputs.shortEntryColor, // Short Entry Level Color + mInputs.shortEntryLineStyle, // Short Entry Style + // + // Short Exit ... + "", + mInputs.shortExitValue, // Short Exit Level + mInputs.shortExitColor, // Short Exit Level Color + mInputs.shortExitLineStyle, // Short Exit Style + // + // Long Entry ... + "", + mInputs.longEntryValue, // Long Entry Level + mInputs.longEntryColor, // Long Entry Level Color + mInputs.longEntryLineStyle, // Long Entry Style + // + // Long Exit ... + "", + mInputs.longExitValue, // Long Exit Level + mInputs.longExitColor, // Long Exit Level Color + mInputs.longExitLineStyle // Long Exit Style + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XRSIInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XRSIInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetMain( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mainBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mainBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMain( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mainBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XRSIInputs mInputs; // Inputs ... + + // + // Buffers ... + double mainBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Main ... + CopyBuffer( + mHandler, + XRSI_MAIN_LINE, + 0, + totalBars, + mainBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xsslc.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xsslc.helper.mq5 new file mode 100644 index 0000000..6198876 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xsslc.helper.mq5 @@ -0,0 +1,408 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXSSLCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XSSLC_BUFFERS +{ + XSSLC_UP_LINE = 0, + XSSLC_DOWN_LINE = 1, +}; + +// +// Input Models ... +struct XSSLCInputs +{ + // + // Props ... + + // + // Market ... + int length; // Length + + // + // Calculation ... + ENUM_MA_METHOD method; // Method + ENUM_APPLIED_PRICE upAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE downAppliedTo; // Down Applied To + + // + // Presentation ... + bool showUp; // Show Up + bool showDown; // Show Down + + // + // Constructor(s) ... + XSSLCInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + length = 0; + + // + // Calculation ... + method = MODE_SMA; + upAppliedTo = PRICE_HIGH; + downAppliedTo = PRICE_LOW; + + // + // Presentation ... + showUp = false; + showDown = false; + } + + // + // Default ... + void Default() + { + // + // Market ... + length = 36; + + // + // Calculation ... + method = MODE_SMA; + upAppliedTo = PRICE_HIGH; + downAppliedTo = PRICE_LOW; + + // + // Presentation ... + showUp = true; + showDown = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, 0); + + // + return result; + } +}; + +// +// Class ... +class XSCXSSLCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXSSLCHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXSSLCHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XSSLCInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(upBuffer, true); + ArraySetAsSeries(downBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xsslc", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, // Length + // + // Calculation ... + "", + mInputs.method, // Method + mInputs.upAppliedTo, // Up Applied To + mInputs.downAppliedTo, // Down Applied To + // + // Presentation ... + "", + mInputs.showUp, // Show Up + mInputs.showDown // Show Down + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XSSLCInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XSSLCInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Up ... + + // + double GetUp( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(upBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return upBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyUp( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + upBuffer, + buffer, + forceClean + // + ); + } + + // + // Down ... + + // + double GetDown( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(downBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return downBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyDown( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + downBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XSSLCInputs mInputs; // Inputs ... + + // + // Buffers ... + double upBuffer[]; + double downBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Up ... + CopyBuffer( + mHandler, + XSSLC_UP_LINE, + 0, + totalBars, + upBuffer + // + ); + + // + // Down ... + CopyBuffer( + mHandler, + XSSLC_DOWN_LINE, + 0, + totalBars, + downBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xstr.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xstr.helper.mq5 new file mode 100644 index 0000000..009f3ba --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xstr.helper.mq5 @@ -0,0 +1,421 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXSTRHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XSTR_BUFFERS +{ + X_STR_TREND_LINE = 0, + X_STR_STATE_LINE = 5, +}; + +// +enum ENUM_XSTR_TREND_STATES +{ + X_STR_BULLISH = 1, // Bullish + X_STR_BEARISH = -1, // Bearish +}; + +// +// Input Models ... +struct XSTRInputs +{ + // + // Props ... + + // + // Market ... + int length; // Length + double multiplier; // Multiplier + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + bool showTrends; // Show Trends + bool fillTrends; // Fill Trends + + // + // Constructor(s) ... + XSTRInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + multiplier = 0; + appliedTo = PRICE_CLOSE; + // + showTrends = false; + fillTrends = false; + } + + // + // Default ... + void Default() + { + // + length = 14; + multiplier = 3.5; + appliedTo = PRICE_MEDIAN; + // + showTrends = true; + fillTrends = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length > 0 && + multiplier > 0 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = length; + + // + return result; + } +}; + +// +// Class ... +class XSCXSTRHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXSTRHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXSTRHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XSTRInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(trendBuffer, true); + ArraySetAsSeries(stateBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xstr", + // + // Inputs ... + // + // ATR ... + "", + mInputs.length, // Length + mInputs.multiplier, // Multiplier + mInputs.appliedTo, // Applied To + // + // Presentation ... + "", + mInputs.showTrends, // Show Trends + mInputs.fillTrends // Fill Trends + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XSTRInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XSTRInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs); + } + + // + // Buffers ... + + // + // Trend ... + + // + double GetTrend( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return trendBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyTrend( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + trendBuffer, + buffer, + forceClean + // + ); + } + + // + // State ... + + // + ENUM_XSTR_TREND_STATES GetState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return (ENUM_XSTR_TREND_STATES)((int)stateBuffer[barIndex]); + } + + // + // Copy Required Buffer ... + int CopyState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + stateBuffer, + buffer, + forceClean + // + ); + } + + // + // Tools ... + + // + ENUM_XSTR_TREND_STATES ToState(double state) + { + return (ENUM_XSTR_TREND_STATES)((int)state); + } + + // + bool IsBullish(double state) + { + // + bool result = false; + + // + result = + // + ToState(state) == X_STR_BULLISH; + // + ; + + // + return result; + } + + // + bool IsBearish(double state) + { + // + bool result = false; + + // + result = + // + ToState(state) == X_STR_BEARISH; + // + ; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XSTRInputs mInputs; // Inputs ... + + // + // Buffers ... + double trendBuffer[]; + double stateBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + int calculatedBars = CountCalculatedBars(); + + // + // Trend ... + CopyBuffer( + mHandler, + X_STR_TREND_LINE, + 0, + totalBars, + trendBuffer + // + ); + + // + // State ... + CopyBuffer( + mHandler, + X_STR_STATE_LINE, + 0, + totalBars, + stateBuffer + // + ); + } +}; + +// +// Tools ... diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtd.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtd.helper.mq5 new file mode 100644 index 0000000..488e7d6 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtd.helper.mq5 @@ -0,0 +1,458 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTDHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XTD_BUFFERS +{ + XTD_BULLISH_LINE = 0, + XTD_BEARISH_LINE = 1, + XTD_SIGNAL_LINE = 2, +}; + +// +// Input Models ... +struct XTDInputs +{ + // + // Props ... + // + int length; // Market Length + bool drawCrosses; // Draw Cross Arrows + + // + // Bullish ... + uchar bullishArrowCode; // Cross Over Arrow Code + color bullishArrowColor; // Cross Over Arrow Color + + // + // Bearish ... + uchar bearishArrowCode; // Cross Under Arrow Code + color bearishArrowColor; // Cross Under Arrow Color + + // + // Constructor(s) ... + XTDInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + drawCrosses = false; + + // + // Bullish ... + bullishArrowCode = 228; + bullishArrowColor = CLR_NONE; + + // + // Bearish ... + bearishArrowCode = 230; + bearishArrowColor = CLR_NONE; + } + + // + // Default ... + void Default() + { + // + length = 14; + drawCrosses = false; + + // + // Bullish ... + bullishArrowCode = 228; + bullishArrowColor = CLR_NONE; + + // + // Bearish ... + bearishArrowCode = 230; + bearishArrowColor = CLR_NONE; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 2 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; + } +}; + +// +// Class ... +class XSCXTDHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXTDHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXTDHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XTDInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(bullishBuffer, true); + ArraySetAsSeries(bearishBuffer, true); + ArraySetAsSeries(signalBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xtd", + // + // Inputs ... + // + mInputs.length, // Market Length + mInputs.drawCrosses, // Draw Cross Arrows + // + // Bullish ... + mInputs.bullishArrowCode, // Cross Over Arrow Code + mInputs.bullishArrowColor, // Cross Over Arrow Color + // + // Bearish ... + mInputs.bearishArrowCode, // Cross Under Arrow Code + mInputs.bearishArrowColor // Cross Under Arrow Color + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XTDInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XTDInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetBullish( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(bullishBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bullishBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyBullish( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + bullishBuffer, + buffer, + forceClean + // + ); + } + + // + double GetBearish( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(bearishBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bearishBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyBearish( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + bearishBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(signalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return signalBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySignal( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + signalBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XTDInputs mInputs; // Inputs ... + + // + // Buffers ... + double bullishBuffer[]; + double bearishBuffer[]; + double signalBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Bullish ... + CopyBuffer( + mHandler, + XTD_BULLISH_LINE, + 0, + totalBars, + bullishBuffer + // + ); + + // + // Bearish ... + CopyBuffer( + mHandler, + XTD_BEARISH_LINE, + 0, + totalBars, + bearishBuffer + // + ); + + // + // Signal ... + CopyBuffer( + mHandler, + XTD_SIGNAL_LINE, + 0, + totalBars, + signalBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtm.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtm.helper.mq5 new file mode 100644 index 0000000..a55a04b --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xtm.helper.mq5 @@ -0,0 +1,310 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTMHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XTM_BUFFERS +{ + XTM_MAIN_LINE = 0 +}; + +// +// Input Models ... +struct XTMInputs +{ + // + // Props ... + // + // Market ... + int maPeriod; // Period + int maShift; // Shift + ENUM_MA_METHOD maMethod; // Method + ENUM_APPLIED_PRICE maAppliedTo; // Applied To + // + // Presentation ... + bool showLine; // Show Line + + // + // Constructor(s) ... + XTMInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + maShift = 0; + maPeriod = 0; + showLine = false; + maMethod = MODE_SMA; + maAppliedTo = PRICE_CLOSE; + } + + // + // Default ... + void Default() + { + // + maShift = 0; + maPeriod = 14; + showLine = true; + maMethod = MODE_SMA; + maAppliedTo = PRICE_CLOSE; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + maPeriod >= 2 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, maPeriod); + + // + return result; + } +}; + +// +// Class ... +class XSCXTMHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXTMHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXTMHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XTMInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(mainBuffer, true); + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xtm", + // + // Inputs ... + // + // Market ... + "", + mInputs.maPeriod, // Period + mInputs.maShift, // Shift + mInputs.maMethod, // Method + mInputs.maAppliedTo, // Applied To + // + // Presentation ... + "", + mInputs.showLine // Show Line + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XTMInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XTMInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetMain( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mainBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mainBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMain( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mainBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XTMInputs mInputs; // Inputs ... + + // + // Buffers ... + double mainBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Main Buffer ... + CopyBuffer( + mHandler, + XTM_MAIN_LINE, + 0, + totalBars, + mainBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xts.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xts.helper.mq5 new file mode 100644 index 0000000..72eb425 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xts.helper.mq5 @@ -0,0 +1,550 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTSHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XTS_BUFFERS +{ + XTS_CURRENT_LINE = 0, + XTS_NEAREST_LINE = 1, + XTS_MEDIEST_LINE = 2, + XTS_FAREST_LINE = 3, +}; + +// +// Input Models ... +struct XTSInputs +{ + // + // Props ... + // + // Current Period ... + ENUM_APPLIED_PRICE currentAppliedTo; // Current Applied To + // + // Nearest Period ... + ENUM_X_PERIOD_METHOD nearestMethod; // How to Find Nearest Period + ENUM_TIMEFRAMES nearestPeriod; // Nearest Time Frame + ENUM_APPLIED_PRICE nearestAppliedTo; // Nearest Applied To + // + // Mediest Period ... + ENUM_X_PERIOD_METHOD mediestMethod; // How to Find Mediest Period + ENUM_TIMEFRAMES mediestPeriod; // Mediest Time Frame + ENUM_APPLIED_PRICE mediestAppliedTo; // Mediest Applied To + // + // Farest Period ... + ENUM_X_PERIOD_METHOD farestMethod; // How to Find Farest Period + ENUM_TIMEFRAMES farestPeriod; // Farest Time Frame + ENUM_APPLIED_PRICE farestAppliedTo; // Farest Applied To + + // + // Constructor(s) ... + XTSInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Current Period ... + currentAppliedTo = PRICE_CLOSE; + // + // Nearest Period ... + nearestMethod = X_PERIOD_NOTHING; + nearestPeriod = NULL; + nearestAppliedTo = PRICE_CLOSE; + // + // Mediest Period ... + mediestMethod = X_PERIOD_NOTHING; + mediestPeriod = NULL; + mediestAppliedTo = PRICE_CLOSE; + // + // Farest Period ... + farestMethod = X_PERIOD_NOTHING; + farestPeriod = NULL; + farestAppliedTo = PRICE_CLOSE; + } + + // + // Default ... + void Default() + { + // + // Current Period ... + currentAppliedTo = PRICE_CLOSE; + // + // Nearest Period ... + nearestMethod = X_PERIOD_AUTO; + nearestPeriod = NULL; + nearestAppliedTo = PRICE_CLOSE; + // + // Mediest Period ... + mediestMethod = X_PERIOD_AUTO; + mediestPeriod = NULL; + mediestAppliedTo = PRICE_CLOSE; + // + // Farest Period ... + farestMethod = X_PERIOD_AUTO; + farestPeriod = NULL; + farestAppliedTo = PRICE_CLOSE; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(nearestMethod, nearestPeriod) && + IsValid(mediestMethod, mediestPeriod) && + IsValid(farestMethod, farestPeriod) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(result, 0); + + // + return result; + } +}; + +// +// Class ... +class XSCXTSHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXTSHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXTSHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XTSInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(currentBuffer, true); + ArraySetAsSeries(nearestBuffer, true); + ArraySetAsSeries(mediestBuffer, true); + ArraySetAsSeries(farestBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xts", + // + // Inputs ... + // + // Current Period ... + "", + mInputs.currentAppliedTo, // Current Applied To + // + // Nearest Period ... + "", + mInputs.nearestMethod, // How to Find Nearest Period + mInputs.nearestPeriod, // Nearest Time Frame + mInputs.nearestAppliedTo, // Nearest Applied To + // + // Mediest Period ... + "", + mInputs.mediestMethod, // How to Find Mediest Period + mInputs.mediestPeriod, // Mediest Time Frame + mInputs.mediestAppliedTo, // Mediest Applied To + // + // Farest Period ... + "", + mInputs.farestMethod, // How to Find Farest Period + mInputs.farestPeriod, // Farest Time Frame + mInputs.farestAppliedTo // Farest Applied To + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XTSInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XTSInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetCurrent( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(currentBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return currentBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyCurrent( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + currentBuffer, + buffer, + forceClean + // + ); + } + + // + double GetNearest( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(nearestBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return nearestBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyNearest( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + nearestBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMediest( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mediestBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mediestBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMediest( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mediestBuffer, + buffer, + forceClean + // + ); + } + + // + double GetFarest( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(farestBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return farestBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFarest( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + farestBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XTSInputs mInputs; // Inputs ... + + // + // Buffers ... + double currentBuffer[]; + double nearestBuffer[]; + double mediestBuffer[]; + double farestBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Current ... + CopyBuffer( + mHandler, + XTS_CURRENT_LINE, + 0, + totalBars, + currentBuffer + // + ); + + // + // Nearest ... + CopyBuffer( + mHandler, + XTS_NEAREST_LINE, + 0, + totalBars, + nearestBuffer + // + ); + + // + // Mediest ... + CopyBuffer( + mHandler, + XTS_MEDIEST_LINE, + 0, + totalBars, + mediestBuffer + // + ); + + // + // Farest ... + CopyBuffer( + mHandler, + XTS_FAREST_LINE, + 0, + totalBars, + farestBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xzg.helper.mq5 b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xzg.helper.mq5 new file mode 100644 index 0000000..a51158d --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Helpers/x-saherelm.xzg.helper.mq5 @@ -0,0 +1,527 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXZGHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +// How to Calculate Up and Down Price ... +enum ENUM_X_ZG_PRICE_MODE +{ + // + X_ZG_PRICE_HIGH_LOW_MODE = 1, + X_ZG_PRICE_OPEN_CLOSE_MODE = 2, +}; + +// +enum ENUM_XZG_BUFFERS +{ + // + XZG_MAIN_LINE = 0, + XZG_PEAKSANDVALES_LINE = 2, + XZG_HIGHS_LINE = 4, + XZG_LOWS_LINE = 5, +}; + +// +// Input Models ... +struct XZGInputs +{ + // + // Props ... + + // + // Market ... + int depth; // Depth + int deviation; // Deviation + int backStep; // Back Step + ENUM_X_ZG_PRICE_MODE mode; // Mode + // + // Presentation ... + bool showZigZag; // Show ZigZag + bool showPeaksAndVales; // Show Peaks and Vales + + // + // Constructor(s) ... + XZGInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + depth = 0; + deviation = 0; + backStep = 0; + mode = X_ZG_PRICE_HIGH_LOW_MODE; + // + // Presentation ... + showZigZag = false; + showPeaksAndVales = false; + } + + // + // Default ... + void Default() + { + // + // Market ... + depth = 12; + deviation = 5; + backStep = 3; + mode = X_ZG_PRICE_HIGH_LOW_MODE; + // + // Presentation ... + showZigZag = true; + showPeaksAndVales = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + depth > 0 && + deviation > 0 && + backStep > 0 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(backStep, depth); + + // + return result; + } +}; + +// +// Class ... +class XSCXZGHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXZGHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXZGHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XZGInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(mainBuffer, true); + ArraySetAsSeries(PeaksAndValesBuffer, true); + ArraySetAsSeries(highsBuffer, true); + ArraySetAsSeries(lowsBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xzg", + // + // Inputs ... + // + // Market ... + "", + mInputs.depth, // Depth + mInputs.deviation, // Deviation + mInputs.backStep, // Back Step + mInputs.mode, // Mode + // + // Presentation ... + "", + mInputs.showZigZag, // Show ZigZag + mInputs.showPeaksAndVales // Show Peaks and Vales + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XZGInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XZGInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetMain( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mainBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mainBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMain( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mainBuffer, + buffer, + forceClean + // + ); + } + + // + double GetPeaksAndVales( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(PeaksAndValesBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return PeaksAndValesBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyPeaksAndVales( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + PeaksAndValesBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(highsBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return highsBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHigh( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + highsBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lowsBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lowsBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lowsBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XZGInputs mInputs; // Inputs ... + + // + // Buffers ... + double mainBuffer[]; + double PeaksAndValesBuffer[]; + double highsBuffer[]; + double lowsBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + + // + // Main Buffer ... + CopyBuffer( + mHandler, + XZG_MAIN_LINE, + 0, + totalBars, + mainBuffer + // + ); + + // + // Peaks and Vales Buffer ... + CopyBuffer( + mHandler, + XZG_PEAKSANDVALES_LINE, + 0, + totalBars, + PeaksAndValesBuffer + // + ); + + // + // Highs Buffer ... + CopyBuffer( + mHandler, + XZG_HIGHS_LINE, + 0, + totalBars, + highsBuffer + // + ); + + // + // Lows Buffer ... + CopyBuffer( + mHandler, + XZG_LOWS_LINE, + 0, + totalBars, + lowsBuffer + // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xama.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xama.mq5 new file mode 100644 index 0000000..714a25d --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xama.mq5 @@ -0,0 +1,348 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAMA Indicator +// --------------------------------------------- +// Name: XAMA +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XAMA Indicator" +#property strict + +// +// Constants ... + +#define ShortName "XAMA" + +// +// Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 1, + X_XAMA_BEARISH = -1, + X_XAMA_NEUTURAL = 0, +}; + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int length = 18; // Period +input int fastEMA = 2; // Fast EMA Period +input int slowEMA = 30; // Slow EMA Period +input int maShift = 0; // Shift +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +// Presentation ... +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XAMA" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed, CLR_NONE +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initializing MA Handler ... + maHandler = iAMA( + _Symbol, + _Period, + length, + fastEMA, + slowEMA, + maShift, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(maHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(fastEMA, slowEMA); + maxLength = MathMax(maxLength, length); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XAMA " + "(" + (string)length + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", length, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle; + candle.Init( + _Symbol, + _Period, + bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XAMA_BULLISH : lineColorIndex == 2 ? X_XAMA_BEARISH + : X_XAMA_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = showLine ? lineColorIndex : 3; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xcc.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xcc.mq5 new file mode 100644 index 0000000..2e11f1c --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xcc.mq5 @@ -0,0 +1,458 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Styles +// --------------------------------------------------- +// Name: XCC +// Description: Candle Styles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XCC" + +// +// Holds an SnapShot of Charts Configuration ... +struct XChartStyle +{ + // + // chart's ID ... + long chartId; + // + // chart's mode ... + ENUM_CHART_MODE mode; + // + // show bid line ... + bool showBidLine; + // + // show ask line ... + bool showAskLine; + // + // show grids on chart ... + bool showGrid; + // + // show volumes ... + bool showVolumes; + // + // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ... + bool showTradeLevels; + // + // chart autoscroll ... + bool autoScroll; + // + // chart quick navigation state ... + bool quickNavigation; + // + // chart's foreground color ... + color foreGroundColor; + // + // chart's background color ... + color backGroundColor; + // + // Up Color ... + color upColor; + // + // Down Color ... + color downColor; + // + // Bullish color ... + color bullishColor; + // + // Bearish color ... + color bearishColor; + // + // grid color ... + color gridColor; + // + // bid line color ... + color bidLineColor; + // + // ask line color ... + color askLineColor; + // + // line mode and doji candlestick color ... + color lineColor; + // + // Color of stop order levels (Stop Loss and Take Profit) ... + color stopColor; + // + // volumes color ... + color volumesColor; +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Chart Style"; +input ENUM_CHART_MODE mode = CHART_CANDLES; // Mode +input color upColor = clrLime; // Up Color +input color downColor = clrRed; // Down Color +input color lineColor = clrLime; // Line mode and Doji candlestick Color +input color bearishColor = clrRed; // Bullish Color +input color bullishColor = clrLime; // Bearish Color +input color volumesColor = clrGreen; // Volumes Color + +// +input group "Presentation"; +input bool showCandles = true; // Show Candles + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XChartStyle chartStyle; +XChartStyle clearStyle; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Apply Chart Style ... + ApplyCustomChartStyle(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[] + // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ +} + +// +// Apply Custom Chart Style ... +void ApplyCustomChartStyle() +{ + // + // Read Current Chart Config and Store it ... + ReadChartStyle(); + + // + // After Reading Current Chart Style ... + // we have to Save Configs and Change Styles ... + clearStyle = chartStyle; + + // + clearStyle.upColor = CLR_NONE; + clearStyle.downColor = CLR_NONE; + clearStyle.lineColor = CLR_NONE; + clearStyle.bullishColor = CLR_NONE; + clearStyle.bearishColor = CLR_NONE; + + // + // Decide to Show or not Candles based on User Input ... + if (showCandles) + { + SetChartStyle(chartStyle); + } + else + { + SetChartStyle(clearStyle); + } +} + +// +// Read Previous Chart Style ... +void ReadChartStyle() +{ + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + chartStyle.chartId = chartId; + + // + // Retrieve Chart Mode ... + chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); + + // + chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); + chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); + chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); + chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); + chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); + chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); + chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); + + // + chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); + chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); + chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); + chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); + chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); + chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); + chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); + chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); + chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); + chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); + chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); + chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); + + // + chartStyle.mode = mode; + chartStyle.upColor = upColor; + chartStyle.downColor = downColor; + chartStyle.lineColor = lineColor; + chartStyle.bearishColor = bearishColor; + chartStyle.bullishColor = bullishColor; + chartStyle.volumesColor = volumesColor; +} + +// +// Set Chart Style ... +void SetChartStyle( + XChartStyle &mChartStyle // Chart Style to Apply +) +{ + // + ApplyChartStyle( + mChartStyle.chartId, + mChartStyle.mode, + mChartStyle.showBidLine, + mChartStyle.showAskLine, + mChartStyle.showGrid, + mChartStyle.showVolumes, + mChartStyle.showTradeLevels, + mChartStyle.autoScroll, + mChartStyle.quickNavigation, + mChartStyle.foreGroundColor, + mChartStyle.backGroundColor, + mChartStyle.upColor, + mChartStyle.downColor, + mChartStyle.bullishColor, + mChartStyle.bearishColor, + mChartStyle.gridColor, + mChartStyle.bidLineColor, + mChartStyle.askLineColor, + mChartStyle.lineColor, + mChartStyle.stopColor, + mChartStyle.volumesColor); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xche.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xche.mq5 new file mode 100644 index 0000000..f47d363 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xche.mq5 @@ -0,0 +1,631 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XCHE +// Description: Chandelier Exit Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHE Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XCHE" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 35; // Length +input int loopback = 26; // Loopback +input double multiplier1 = 3.0; // 1st Multiplier +input double multiplier2 = 3.5; // 2nd Multiplier + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showLongExit1Line = true; // Show 1st Long Exit +input bool showShortExit1Line = true; // Show 1st Short Exit +input bool showLongExit2Line = true; // Show 2st Long Exit +input bool showShortExit2Line = true; // Show 2st Short Exit + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +// Long Exit 1 ... +#define longExit1BufferIndex 0 +double longExit1Buffer[]; + +// +#property indicator_label1 "XCHE LE 1" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_DOT + +// +// Short Exit 1 ... +#define shortExit1BufferIndex 1 +double shortExit1Buffer[]; + +// +#property indicator_label2 "XCHE SE 1" +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color2 clrRed + +// +// Long Exit 2 ... +#define longExit2BufferIndex 2 +double longExit2Buffer[]; + +// +#property indicator_label3 "XCHE LE 2" +#property indicator_type3 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color3 clrAqua + +// +// Short Exit 2 ... +#define shortExit2BufferIndex 3 +double shortExit2Buffer[]; + +// +#property indicator_label4 "XCHE SE 2" +#property indicator_type4 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color4 clrMagenta + +// +// START Arrows ... + +// +// Long Exit 1 Start ... +#define longExit1StartBufferIndex 4 +double longExit1StartBuffer[]; + +// +#property indicator_label5 "XCHE LES 1" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrLime + +// +// Short Exit 1 Start ... +#define shortExit1StartBufferIndex 5 +double shortExit1StartBuffer[]; + +// +#property indicator_label6 "XCHE SES 1" +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrRed + +// +// Long Exit 2 Start ... +#define longExit2StartBufferIndex 6 +double longExit2StartBuffer[]; + +// +#property indicator_label7 "XCHE LES 2" +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrAqua + +// +// Short Exit 2 Start ... +#define shortExit2StartBufferIndex 7 +double shortExit2StartBuffer[]; + +// +#property indicator_label8 "XCHE SES 2" +#property indicator_type8 DRAW_ARROW +#property indicator_color8 clrMagenta + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// Working Array ... +double work[][6]; +#define hi1Idx 0 +#define lo1Idx 1 +#define hi2Idx 2 +#define lo2Idx 3 +#define trend1Idx 4 +#define trend2Idx 5 + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart mPeriod is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + if (Bars(_Symbol, _Period) < rates_total) + { + return (prev_calculated); + } + + // + if (ArrayRange(work, 0) != rates_total) + { + ArrayResize(work, rates_total); + } + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + low, + close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + loopback >= 0; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(length, loopback); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + uint arrowCode = 159; + + // + // LEVEL 1 ... + + // + // Long Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit1DrawType = showLongExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit1StartDrawType = showLongExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit1BufferIndex, longExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_SHOW_DATA, showLongExit1Line); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_DRAW_TYPE, longExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit1StartBufferIndex, longExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_DRAW_TYPE, longExit1StartDrawType); + + // + // Short Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit1DrawType = showShortExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit1StartDrawType = showShortExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit1BufferIndex, shortExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_SHOW_DATA, showShortExit1Line); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_DRAW_TYPE, shortExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit1StartBufferIndex, shortExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_DRAW_TYPE, shortExit1StartDrawType); + + // + // LEVEL 2 ... + + // + // Long Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit2DrawType = showLongExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit2StartDrawType = showLongExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit2BufferIndex, longExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_SHOW_DATA, showLongExit2Line); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_DRAW_TYPE, longExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit2StartBufferIndex, longExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_DRAW_TYPE, longExit2StartDrawType); + + // + // Short Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit2DrawType = showShortExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit2StartDrawType = showShortExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit2BufferIndex, shortExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_SHOW_DATA, showShortExit2Line); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_DRAW_TYPE, shortExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit2StartBufferIndex, shortExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_DRAW_TYPE, shortExit2StartDrawType); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int prevCalculated, // Previous Calculated + int ratesTotal, // Total Rates + const double &open[], // Rates Open ... + const double &high[], // Rates High ... + const double &low[], // Rates Low ... + const double &close[] // Rates Close ... +) +{ + // + // Cleanup Buffers ... + longExit1Buffer[bar_index] = longExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index] = shortExit1StartBuffer[bar_index] = EMPTY_VALUE; + longExit2Buffer[bar_index] = longExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index] = shortExit2StartBuffer[bar_index] = EMPTY_VALUE; + + // + int start = MathMax(bar_index - loopback, 0); + + // + // Calculate ATR Value ... + double atrValue = 0; + for (int k = 1; k <= length && (bar_index - k - 1) >= 0; k++) + { + // + atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) - + MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]); + } + atrValue /= (double)length; + + // + // Retrieve Highest High and Lowest Lows ... + double loopbackMax = high[ArrayMaximum(high, start, loopback)]; + double loopbackMin = low[ArrayMinimum(low, start, loopback)]; + + // + // Fill Multi Dimesional Working Array ... + work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue; + work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue; + work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue; + work[bar_index][lo2Idx] = loopbackMin + multiplier2 * atrValue; + work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0; + work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0; + + // + if (bar_index > 0) + { + // + // Calculate Trends ... + if (close[bar_index] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][trend1Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][trend1Idx] = -1; + } + + // + if (close[bar_index] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][trend2Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][trend2Idx] = -1; + } + + // + // Calculate Exit Values ... + + // + // Exit 1 ... + + // + // Long ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == 1) + { + // + if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx]; + } + + // + longExit1Buffer[bar_index] = work[bar_index][hi1Idx]; + + // + if (longExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit1StartBuffer[bar_index] = longExit1Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == -1) + { + // + if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx]; + } + + // + shortExit1Buffer[bar_index] = work[bar_index][lo1Idx]; + + // + if (shortExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index]; + } + } + + // + // Exit 2 ... + + // + // Long ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == 1) + { + if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx]; + } + + // + longExit2Buffer[bar_index] = work[bar_index][hi2Idx]; + + // + if (longExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit2StartBuffer[bar_index] = longExit2Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == -1) + { + // + if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx]; + } + + // + shortExit2Buffer[bar_index] = work[bar_index][lo2Idx]; + + // + if (shortExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index]; + } + } + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchlh.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchlh.mq5 new file mode 100644 index 0000000..3df87f0 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchlh.mq5 @@ -0,0 +1,816 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel LH Oscillator +// --------------------------------------------------- +// Name: XCHLH +// Description: detecting HH and LL based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHLH Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHLH" + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotHHArrowCode = 234; // Hot HH Arrow Code +input color hotHHArrowColor = clrAqua; // Hot HH Arrow Color +input uchar hotLLArrowCode = 233; // Hot LL Arrow Code +input color hotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcLength = 28; // Length +input double lcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE lcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE lcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcHHColor = clrAqua; // Highest High Color +input color lcLLColor = clrFuchsia; // Lowest Low Color +input group "LC Drawings"; +input bool lcDrawHH = true; // Draw Highest High +input bool lcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcLength = 14; // Length +input double mcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE mcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE mcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcHHColor = clrLime; // Highest High Color +input color mcLLColor = clrRed; // Lowest Low Color +input group "MC Drawings"; +input bool mcDrawHH = true; // Draw Highest High +input bool mcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scLength = 7; // Length +input double scThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE scHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE scLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_DOT; // Draw Style +input color scHHColor = clrLightBlue; // Highest High Color +input color scLLColor = clrLightSalmon; // Lowest Low Color +input group "SC Drawings"; +input bool scDrawHH = true; // Draw Highest High +input bool scDrawLL = true; // Draw Lowest Low +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +// #property indicator_separate_window +#property indicator_chart_window + +// +#property indicator_buffers 7 +// #property indicator_plots 6 +#property indicator_plots 0 + +// +// LC ... +#define lcHHBufferIndex 0 +#define lcLLBufferIndex 1 + +// +double lcHHBuffer[]; +double lcLLBuffer[]; + +// +// MC ... +#define mcHHBufferIndex 2 +#define mcLLBufferIndex 3 + +// +double mcHHBuffer[]; +double mcLLBuffer[]; + +// +// SC ... +#define scHHBufferIndex 4 +#define scLLBufferIndex 5 + +// +double scHHBuffer[]; +double scLLBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcLength, mcLength); + maxLength = MathMax(maxLength, scLength); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = + lcLength >= 4 && + lcLength > mcLength && + lcLength > scLength; + bool isMCInputsValid = + mcLength >= 4 && + mcLength > scLength && + mcLength < lcLength; + bool isSCInputsValid = + scLength >= 4 && + scLength < mcLength && + scLength < lcLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + LCCalculateBuffers(bar_index); + + // + // MC ... + MCCalculateBuffers(bar_index); + + // + // SC ... + SCCalculateBuffers(bar_index); + + // + // SIGNAL ... + SignalCalculateBuffers(bar_index); + + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC HH Buffer ... + string lcHHBufferLabel = ShortName + " LC HH (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcHHDrawType = lcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_BEGIN, lcLength); + // PlotIndexSetString(lcHHBufferIndex, PLOT_LABEL, lcHHBufferLabel); + // PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_COLOR, lcHHColor); + // PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + // PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + // PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_TYPE, lcHHDrawType); + + // + // LC LL Buffer ... + string lcLLBufferLabel = ShortName + " LC LL (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcLLDrawType = lcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_BEGIN, lcLength); + // PlotIndexSetString(lcLLBufferIndex, PLOT_LABEL, lcLLBufferLabel); + // PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_COLOR, lcLLColor); + // PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + // PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + // PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_TYPE, lcLLDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC HH Buffer ... + string mcHHBufferLabel = ShortName + " MC HH (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcHHDrawType = mcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_BEGIN, mcLength); + // PlotIndexSetString(mcHHBufferIndex, PLOT_LABEL, mcHHBufferLabel); + // PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_COLOR, mcHHColor); + // PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + // PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + // PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_TYPE, mcHHDrawType); + + // + // MC LL Buffer ... + string mcLLBufferLabel = ShortName + " MC LL (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcLLDrawType = mcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_BEGIN, mcLength); + // PlotIndexSetString(mcLLBufferIndex, PLOT_LABEL, mcLLBufferLabel); + // PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_COLOR, mcLLColor); + // PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + // PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + // PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_TYPE, mcLLDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC HH Buffer ... + string scHHBufferLabel = ShortName + " SC HH (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scHHDrawType = scDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_BEGIN, scLength); + // PlotIndexSetString(scHHBufferIndex, PLOT_LABEL, scHHBufferLabel); + // PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_COLOR, scHHColor); + // PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + // PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + // PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_TYPE, scHHDrawType); + + // + // SC LL Buffer ... + string scLLBufferLabel = ShortName + " SC LL (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scLLDrawType = scDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_BEGIN, scLength); + // PlotIndexSetString(scLLBufferIndex, PLOT_LABEL, scLLBufferLabel); + // PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_COLOR, scLLColor); + // PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + // PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + // PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_TYPE, scLLDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Calculations ... +void LCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = lcLength; + ENUM_SERIESMODE hhMode = lcHHMode; + ENUM_SERIESMODE llMode = lcLLMode; + double threshold = PipsToPrice(lcThresholdInPips); + + // + int hhIdx = iHighest( + _Symbol, + _Period, + hhMode, + length, + bar_index + // + ); + double hh = iHigh( + _Symbol, + _Period, + hhIdx); + double hhValue = hh + threshold; + + // + int llIdx = iLowest( + _Symbol, + _Period, + llMode, + length, + bar_index + // + ); + double ll = iLow( + _Symbol, + _Period, + llIdx); + double llValue = ll - threshold; + + // + lcHHBuffer[bar_index] = hhValue; + lcLLBuffer[bar_index] = llValue; +} + +// +// MC Calculations ... +void MCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = mcLength; + ENUM_SERIESMODE hhMode = mcHHMode; + ENUM_SERIESMODE llMode = mcLLMode; + double threshold = PipsToPrice(mcThresholdInPips); + + // + int hhIdx = iHighest( + _Symbol, + _Period, + hhMode, + length, + bar_index + // + ); + double hh = iHigh( + _Symbol, + _Period, + hhIdx); + double hhValue = hh + threshold; + + // + int llIdx = iLowest( + _Symbol, + _Period, + llMode, + length, + bar_index + // + ); + double ll = iLow( + _Symbol, + _Period, + llIdx); + double llValue = ll - threshold; + + // + mcHHBuffer[bar_index] = hhValue; + mcLLBuffer[bar_index] = llValue; +} + +// +// SC Calculations ... +void SCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = scLength; + ENUM_SERIESMODE hhMode = scHHMode; + ENUM_SERIESMODE llMode = scLLMode; + double threshold = PipsToPrice(scThresholdInPips); + + // + int hhIdx = iHighest( + _Symbol, + _Period, + hhMode, + length, + bar_index + // + ); + double hh = iHigh( + _Symbol, + _Period, + hhIdx); + double hhValue = hh + threshold; + + // + int llIdx = iLowest( + _Symbol, + _Period, + llMode, + length, + bar_index + // + ); + double ll = iLow( + _Symbol, + _Period, + llIdx); + double llValue = ll - threshold; + + // + scHHBuffer[bar_index] = hhValue; + scLLBuffer[bar_index] = llValue; +} + +// +// SIGNAL Calculations ... +void SignalCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC Values ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + double lcDelta = lcHH - lcLL; + double lcAvg = lcDelta / 2; + + // + // MC Values ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + double mcDelta = mcHH - mcLL; + double mcAvg = mcDelta / 2; + + // + // SC Values ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + double scDelta = scHH - scLL; + double scAvg = scDelta / 2; + + // + // Min Value ... + double minValue = MathMin( + scLL, mcLL); + minValue = MathMin( + lcLL, minValue); + + // + // Max Value ... + double maxValue = MathMin( + scHH, mcHH); + maxValue = MathMin( + lcHH, maxValue); +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + // + double lcHH1 = lcHHBuffer[bar_index + 1]; + double lcLL1 = lcLLBuffer[bar_index + 1]; + + // + // MC ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + // + double mcHH1 = mcHHBuffer[bar_index + 1]; + double mcLL1 = mcLLBuffer[bar_index + 1]; + + // + // SC ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + // + double scHH1 = scHHBuffer[bar_index + 1]; + double scLL1 = scLLBuffer[bar_index + 1]; + + // + bool isHotLLState = scLL == mcLL && mcLL == lcLL; + bool isHotLLState1 = scLL1 == mcLL1 && mcLL1 == lcLL1; + // + bool isHotHHState = scHH == mcHH && mcHH == lcHH; + bool isHotHHState1 = scHH1 == mcHH1 && mcHH1 == lcHH1; + + // + bool isHotLL = isHotLLState && !isHotLLState1; + bool isHotHH = isHotHHState && !isHotHHState1; + + // + double hotStateValue = X_XCHLH_NEUTURAL; + if (isHotHH) + { + hotStateValue = X_XCHLH_HOT_HH; + } + else if (isHotLL) + { + hotStateValue = X_XCHLH_HOT_LL; + } + + // + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle; + candle.Init( + _Symbol, + _Period, + bar_index + // + ); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotHHArea = hotStateValue == 1; + bool isHotLLArea = hotStateValue == -1; + if (isHotHHArea || isHotLLArea) + { + // + bool isHH = isHotHHArea; + + // + double price = isHH ? candle.high : candle.low; + ENUM_ARROW_ANCHOR anchor = isHH ? ANCHOR_BOTTOM : ANCHOR_TOP; + color clr = isHH ? hotHHArrowColor : hotLLArrowColor; + uchar arrowCode = isHH ? hotHHArrowCode : hotLLArrowCode; + string name = "HOT " + (isHH ? "HH" : "LL") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr, + STYLE_SOLID, + 1); + } + } +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchma.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchma.mq5 new file mode 100644 index 0000000..e59bc43 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xchma.mq5 @@ -0,0 +1,1134 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel Moving Averages Oscillator +// ---------------------------------------------------------------- +// Name: XCHMA +// Description: trend detecting based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHMA Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHMA" + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotBullishArrowCode = 228; // Hot Bullish Arrow Code +input color hotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color +input uchar hotBearishArrowCode = 230; // Hot Bearish Arrow Code +input color hotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcFastLength = 20; // Fast Length +input int lcSlowLength = 50; // Slow Length +input ENUM_MA_METHOD lcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE lcAppliedTo = PRICE_CLOSE; // Applied To +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcFastColor = clrAqua; // Fast Color +input color lcSlowColor = clrFuchsia; // Slow Color +input group "LC Drawings"; +input bool lcDrawFast = true; // Draw Fast +input bool lcDrawSlow = true; // Draw Slow +input bool lcDrawCrosses = true; // Draw Cross Lines + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcFastLength = 10; // Fast Length +input int mcSlowLength = 30; // Slow Length +input ENUM_MA_METHOD mcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE mcAppliedTo = PRICE_CLOSE; // Applied To +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcFastColor = clrLime; // Fast Color +input color mcSlowColor = clrRed; // Slow Color +input group "MC Drawings"; +input bool mcDrawFast = true; // Draw Fast +input bool mcDrawSlow = true; // Draw Slow +input bool mcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scFastLength = 7; // Fast Length +input int scSlowLength = 14; // Slow Length +input ENUM_MA_METHOD scMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE scAppliedTo = PRICE_CLOSE; // Applied To +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_SOLID; // Draw Style +input color scFastColor = clrLightBlue; // Fast Color +input color scSlowColor = clrLightSalmon; // Slow Color +input group "SC Drawings"; +input bool scDrawFast = true; // Draw Fast +input bool scDrawSlow = true; // Draw Slow +input bool scDrawCrosses = false; // Draw Cross Lines +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +// #property indicator_separate_window +#property indicator_chart_window + +// +#property indicator_buffers 7 +// #property indicator_plots 6 +#property indicator_plots 0 + +// +// LC ... +#define lcFastBufferIndex 0 +#define lcSlowBufferIndex 1 + +// +double lcFastBuffer[]; +double lcSlowBuffer[]; + +// +// MC ... +#define mcFastBufferIndex 2 +#define mcSlowBufferIndex 3 + +// +double mcFastBuffer[]; +double mcSlowBuffer[]; + +// +// SC ... +#define scFastBufferIndex 4 +#define scSlowBufferIndex 5 + +// +double scFastBuffer[]; +double scSlowBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// LC ... +int lcFastHandler = INVALID_HANDLE; +int lcSlowHandler = INVALID_HANDLE; + +// +// MC ... +int mcFastHandler = INVALID_HANDLE; +int mcSlowHandler = INVALID_HANDLE; + +// +// SC ... +int scFastHandler = INVALID_HANDLE; +int scSlowHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init All Required Handlers ... + if (!InitHandlers()) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcFastLength, lcSlowLength); + + // + // Get Retrieved Values from indicators ... + // + // LC ... + int lcFastCalculatedBars = BarsCalculated(lcFastHandler); + int lcSlowCalculatedBars = BarsCalculated(lcSlowHandler); + + // + // MC ... + int mcFastCalculatedBars = BarsCalculated(mcFastHandler); + int mcSlowCalculatedBars = BarsCalculated(mcSlowHandler); + + // + // SC ... + int scFastCalculatedBars = BarsCalculated(scFastHandler); + int scSlowCalculatedBars = BarsCalculated(scSlowHandler); + + // + // Check Calculated Bars ... + if ( + // + // LC ... + lcFastCalculatedBars < maxLength || + lcSlowCalculatedBars < maxLength || + // + // MC ... + mcFastCalculatedBars < maxLength || + mcSlowCalculatedBars < maxLength || + // + // SC ... + scFastCalculatedBars < maxLength || + scSlowCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Copy Buffers from indicators ... + // + // LC ... + int lcFastCopiedItems = CopyBuffer(lcFastHandler, 0, 0, limit + 1, lcFastBuffer); + int lcSlowCopiedItems = CopyBuffer(lcSlowHandler, 0, 0, limit + 1, lcSlowBuffer); + + // + // MC ... + int mcFastCopiedItems = CopyBuffer(mcFastHandler, 0, 0, limit + 1, mcFastBuffer); + int mcSlowCopiedItems = CopyBuffer(mcSlowHandler, 0, 0, limit + 1, mcSlowBuffer); + + // + // SC ... + int scFastCopiedItems = CopyBuffer(scFastHandler, 0, 0, limit + 1, scFastBuffer); + int scSlowCopiedItems = CopyBuffer(scSlowHandler, 0, 0, limit + 1, scSlowBuffer); + + // + // Check Copied Items Number ... + if ( + // + // LC ... + lcFastCopiedItems <= 0 || + lcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = lcFastLength >= 4 && lcSlowLength > lcFastLength; + bool isMCInputsValid = mcFastLength >= 4 && mcSlowLength > mcFastLength; + bool isSCInputsValid = scFastLength >= 4 && scSlowLength > scFastLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid && + lcFastLength > mcFastLength && + mcFastLength > scFastLength) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Init Handlers ... +bool InitHandlers() +{ + // + bool result = false; + + // + // LC ... + result = LCInitHandlers(); + if (!result) + { + return result; + } + + // + // MC ... + result = MCInitHandlers(); + if (!result) + { + return result; + } + + // + // SC ... + result = SCInitHandlers(); + if (!result) + { + return result; + } + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC Fast Buffer ... + string lcFastBufferLabel = ShortName + " LC Fast (" + (string)lcFastLength + ")"; + ENUM_DRAW_TYPE lcFastDrawType = lcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcFastBuffer, true); + SetIndexBuffer(lcFastBufferIndex, lcFastBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(lcFastBufferIndex, lcFastBuffer, INDICATOR_DATA); + // PlotIndexSetString(lcFastBufferIndex, PLOT_LABEL, lcFastBufferLabel); + // PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_COLOR, lcFastColor); + // PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + // PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + // PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_BEGIN, lcFastLength); + // PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_TYPE, lcFastDrawType); + + // + // LC Slow Buffer ... + string lcSlowBufferLabel = ShortName + " LC Slow (" + (string)lcSlowLength + ")"; + ENUM_DRAW_TYPE lcSlowDrawType = lcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcSlowBuffer, true); + SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer, INDICATOR_DATA); + // PlotIndexSetString(lcSlowBufferIndex, PLOT_LABEL, lcSlowBufferLabel); + // PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_COLOR, lcSlowColor); + // PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + // PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + // PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_BEGIN, lcSlowLength); + // PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_TYPE, lcSlowDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC Fast Buffer ... + string mcFastBufferLabel = ShortName + " MC Fast (" + (string)mcFastLength + ")"; + ENUM_DRAW_TYPE mcFastDrawType = mcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcFastBuffer, true); + SetIndexBuffer(mcFastBufferIndex, mcFastBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(mcFastBufferIndex, mcFastBuffer, INDICATOR_DATA); + // PlotIndexSetString(mcFastBufferIndex, PLOT_LABEL, mcFastBufferLabel); + // PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_COLOR, mcFastColor); + // PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + // PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + // PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_BEGIN, mcFastLength); + // PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_TYPE, mcFastDrawType); + + // + // MC Slow Buffer ... + string mcSlowBufferLabel = ShortName + " MC Slow (" + (string)mcSlowLength + ")"; + ENUM_DRAW_TYPE mcSlowDrawType = mcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcSlowBuffer, true); + SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer, INDICATOR_DATA); + // PlotIndexSetString(mcSlowBufferIndex, PLOT_LABEL, mcSlowBufferLabel); + // PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_COLOR, mcSlowColor); + // PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + // PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + // PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_BEGIN, mcSlowLength); + // PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_TYPE, mcSlowDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC Fast Buffer ... + string scFastBufferLabel = ShortName + " SC Fast (" + (string)scFastLength + ")"; + ENUM_DRAW_TYPE scFastDrawType = scDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scFastBuffer, true); + SetIndexBuffer(scFastBufferIndex, scFastBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(scFastBufferIndex, scFastBuffer, INDICATOR_DATA); + // PlotIndexSetString(scFastBufferIndex, PLOT_LABEL, scFastBufferLabel); + // PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_COLOR, scFastColor); + // PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + // PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + // PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_BEGIN, scFastLength); + // PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_TYPE, scFastDrawType); + + // + // SC Slow Buffer ... + string scSlowBufferLabel = ShortName + " SC Slow (" + (string)scSlowLength + ")"; + ENUM_DRAW_TYPE scSlowDrawType = scDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scSlowBuffer, true); + SetIndexBuffer(scSlowBufferIndex, scSlowBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(scSlowBufferIndex, scSlowBuffer, INDICATOR_DATA); + // PlotIndexSetString(scSlowBufferIndex, PLOT_LABEL, scSlowBufferLabel); + // PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_COLOR, scSlowColor); + // PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + // PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + // PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_BEGIN, scSlowLength); + // PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_TYPE, scSlowDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Init Handlers ... +bool LCInitHandlers() +{ + // + ResetLastError(); + + // + // LC Fast Handler ... + lcFastHandler = iMA( + _Symbol, + _Period, + lcFastLength, + 0, + lcMethod, + lcAppliedTo); + if (lcFastHandler == INVALID_HANDLE) + { + return false; + } + + // + // LC Slow Handler ... + lcSlowHandler = iMA( + _Symbol, + _Period, + lcSlowLength, + 0, + lcMethod, + lcAppliedTo); + if (lcSlowHandler == INVALID_HANDLE) + { + return false; + } + + // + return true; +} + +// +// MC Init Handlers ... +bool MCInitHandlers() +{ + // + ResetLastError(); + + // + // MC Fast Handler ... + mcFastHandler = iMA( + _Symbol, + _Period, + mcFastLength, + 0, + mcMethod, + mcAppliedTo); + if (mcFastHandler == INVALID_HANDLE) + { + return false; + } + + // + // MC Slow Handler ... + mcSlowHandler = iMA( + _Symbol, + _Period, + mcSlowLength, + 0, + mcMethod, + mcAppliedTo); + if (mcSlowHandler == INVALID_HANDLE) + { + return false; + } + + // + return true; +} + +// +// SC Init Handlers ... +bool SCInitHandlers() +{ + // + ResetLastError(); + + // + // SC Fast Handler ... + scFastHandler = iMA( + _Symbol, + _Period, + scFastLength, + 0, + scMethod, + scAppliedTo); + if (scFastHandler == INVALID_HANDLE) + { + return false; + } + + // + // SC Slow Handler ... + scSlowHandler = iMA( + _Symbol, + _Period, + scSlowLength, + 0, + scMethod, + scAppliedTo); + if (scSlowHandler == INVALID_HANDLE) + { + return false; + } + + // + return true; +} + +// +// LC State ... +double GetLCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossedOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossedUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// MC State ... +double GetMCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossedOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossedUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// SC State ... +double GetSCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossedOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossedUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcFast = lcFastBuffer[bar_index]; + double lcSlow = lcSlowBuffer[bar_index]; + // + double lcFastPrev = lcFastBuffer[bar_index + 1]; + double lcSlowPrev = lcSlowBuffer[bar_index + 1]; + // + double lcState = GetLCState(bar_index); + + // + // MC ... + double mcFast = mcFastBuffer[bar_index]; + double mcSlow = mcSlowBuffer[bar_index]; + // + double mcFastPrev = mcFastBuffer[bar_index + 1]; + double mcSlowPrev = mcSlowBuffer[bar_index + 1]; + // + double mcState = GetMCState(bar_index); + + // + // SC ... + double scFast = scFastBuffer[bar_index]; + double scSlow = scSlowBuffer[bar_index]; + // + double scFastPrev = scFastBuffer[bar_index + 1]; + double scSlowPrev = scSlowBuffer[bar_index + 1]; + // + double scState = GetSCState(bar_index); + + // + // Detect HOT Bearish Area ... + bool isHotBearishArea = + lcFast < lcSlow && + mcFast < mcSlow && + scFast < scSlow; + // + bool isPrevHotBearishArea = + lcFastPrev < lcSlowPrev && + mcFastPrev < mcSlowPrev && + scFastPrev < scSlowPrev; + + // + // Detect HOT Bearish Area ... + bool isHotBullishArea = + lcFast > lcSlow && + mcFast > mcSlow && + scFast > scSlow; + // + bool isPrevHotBullishArea = + lcFastPrev > lcSlowPrev && + mcFastPrev > mcSlowPrev && + scFastPrev > scSlowPrev; + + // + // Generate HotState Value ... + double hotStateValue = + isHotBullishArea && !isPrevHotBullishArea + ? 1 + : isHotBearishArea && !isPrevHotBearishArea + ? -1 + : 0; + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle; + candle.Init( + _Symbol, + _Period, + bar_index + // + ); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotBullishArea = hotStateValue == 1; + bool isHotBearishArea = hotStateValue == -1; + if (isHotBullishArea || isHotBearishArea) + { + // + bool isBull = isHotBullishArea; + + // + double price = isBull ? candle.low : candle.high; + ENUM_ARROW_ANCHOR anchor = isBull ? ANCHOR_TOP : ANCHOR_BOTTOM; + color clr = isBull ? hotBullishArrowColor : hotBearishArrowColor; + uchar arrowCode = isBull ? hotBullishArrowCode : hotBearishArrowCode; + string name = "HOT " + (isBull ? "Bullish" : "Bearish") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); + } + } + + // + // Draw LC Crosses ... + if (lcDrawCrosses) + { + // + double lcStateValue = GetLCState(bar_index); + bool isLcFastCrossedOverSlow = lcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isLcFastCrossedUnderSlow = lcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isLcFastCrossedOverSlow || isLcFastCrossedUnderSlow) + { + // + bool isBull = isLcFastCrossedOverSlow; + + // + color clr = isBull ? lcFastColor : lcSlowColor; + string name = "LC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw MC Crosses ... + if (mcDrawCrosses) + { + // + double mcStateValue = GetMCState(bar_index); + bool isMcFastCrossedOverSlow = mcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isMcFastCrossedUnderSlow = mcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isMcFastCrossedOverSlow || isMcFastCrossedUnderSlow) + { + // + bool isBull = isMcFastCrossedOverSlow; + + // + color clr = isBull ? mcFastColor : mcSlowColor; + string name = "MC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw SC Crosses ... + if (scDrawCrosses) + { + // + double scStateValue = GetSCState(bar_index); + bool isScFastCrossedOverSlow = scStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isScFastCrossedUnderSlow = scStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isScFastCrossedOverSlow || isScFastCrossedUnderSlow) + { + // + bool isBull = isScFastCrossedOverSlow; + + // + color clr = isBull ? scFastColor : scSlowColor; + string name = "SC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xct.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xct.mq5 new file mode 100644 index 0000000..25b3b07 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xct.mq5 @@ -0,0 +1,261 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XCT +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCT Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XCT" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input color clr = clrYellow; // Text Color +input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; // Text Position + +// +input group "Presentation"; +input bool showCandleTime = true; // Show Candle Time + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (showCandleTime) + { + CreateIndicatorObject(); + } + else + { + ObjectDelete(0, ShortName); + } + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + ulong chID = FindChartID( + _Symbol, + _Period + // + ); + + // + // Delete Object ... + ObjectDelete(chID, ShortName); + + // + Comment(""); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(time, true); + + // + if (!showCandleTime) + { + return rates_total; + } + + // + ulong chID = FindChartID( + _Symbol, + _Period + // + ); + + // + XBarRemainsTime barRemains; + barRemains.Init( + _Symbol, + _Period + // + ); + + // + string msg = barRemains + .ToString( + "", + "", + "", + "", + "", + ":", + true + // + ); + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + // + string _sp = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in: " + msg; + + // + ObjectSetInteger(chID, ShortName, OBJPROP_COLOR, clr); + ObjectSetString(chID, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(chID, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(chID, ShortName, OBJPROP_FONT, "Courier"); + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +void CreateIndicatorObject() +{ + // + if (!showCandleTime) + { + return; + } + + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, corner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + + // + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (corner) + { + case CORNER_LEFT_UPPER: + Anchor = ANCHOR_LEFT_UPPER; + break; + case CORNER_RIGHT_UPPER: + Anchor = ANCHOR_RIGHT_UPPER; + break; + case CORNER_LEFT_LOWER: + Anchor = ANCHOR_LEFT_LOWER; + break; + case CORNER_RIGHT_LOWER: + Anchor = ANCHOR_RIGHT_LOWER; + break; + } + + // + ObjectSetInteger(0, ShortName, OBJPROP_ANCHOR, Anchor); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xdon.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xdon.mq5 new file mode 100644 index 0000000..c96e2bf --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xdon.mq5 @@ -0,0 +1,366 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XDON +// Description: DONCHAIN Channel ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XDON Indicator" +#property strict + +// +#define ShortName "XDON" + +// +// INPUT ... + +// +input group "Market"; +input int length = 52; // Market Length +input double offset = 0; // Offset + +// +input group "Presentation"; +input bool showOpen = true; // Show Open +input bool showHigh = true; // Show High +input bool showClose = true; // Show Close +input bool showLow = true; // Show Low + +// +// BUFFERS ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +#define upperOBufferIndex 0 +double upperOBuffer[]; + +// +#property indicator_label1 "XDON OU" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrCornflowerBlue +#property indicator_width1 2 + +// +#define lowerOBufferIndex 1 +double lowerOBuffer[]; + +// +#property indicator_label2 "XDON OL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrCornflowerBlue +#property indicator_width2 2 + +// +#define upperCBufferIndex 2 +double upperCBuffer[]; + +// +#property indicator_label3 "XDON CU" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrCoral +#property indicator_width3 2 + +// +#define lowerCBufferIndex 3 +double lowerCBuffer[]; + +// +#property indicator_label4 "XDON CL" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrCoral +#property indicator_width4 2 + +// +#define upperHBufferIndex 4 +double upperHBuffer[]; + +// +#property indicator_label5 "XDON HU" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_width5 2 + +// +#define lowerHBufferIndex 5 +double lowerHBuffer[]; + +// +#property indicator_label6 "XDON HL" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_width6 2 + +// +#define upperLBufferIndex 6 +double upperLBuffer[]; + +// +#property indicator_label7 "XDON LU" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrDarkOrchid +#property indicator_width7 2 + +// +#define lowerLBufferIndex 7 +double lowerLBuffer[]; + +// +#property indicator_label8 "XDON LL" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrDarkOrchid +#property indicator_width8 2 + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + if (rates_total < length - 1) + { + return prev_calculated; + } + + // + int start = prev_calculated == 0 + ? length + : prev_calculated - 1; + + // + // Main Loop ... + for (int barIndex = start; barIndex < rates_total; barIndex++) + { + // + // OPEN ... + + // + double upperOValue = open[ArrayMaximum(open, barIndex - length + 1, length)]; + double lowerOValue = open[ArrayMinimum(open, barIndex - length + 1, length)]; + + // + double oDelta = MathAbs(upperOValue - lowerOValue); + double oOffsetValue = oDelta * (offset) * 0.01; + + // + upperOBuffer[barIndex] = upperOValue - oOffsetValue; + lowerOBuffer[barIndex] = lowerOValue + oOffsetValue; + + // + // CLOSE ... + + // + double upperCValue = close[ArrayMaximum(close, barIndex - length + 1, length)]; + double lowerCValue = close[ArrayMinimum(close, barIndex - length + 1, length)]; + + // + double cDelta = MathAbs(upperCValue - lowerCValue); + double cOffsetValue = cDelta * (offset) * 0.01; + + // + upperCBuffer[barIndex] = upperCValue - cOffsetValue; + lowerCBuffer[barIndex] = lowerCValue + cOffsetValue; + + // + // HIGH ... + + // + double upperHValue = high[ArrayMaximum(high, barIndex - length + 1, length)]; + double lowerHValue = high[ArrayMinimum(high, barIndex - length + 1, length)]; + + // + double hDelta = MathAbs(upperHValue - lowerHValue); + double hOffsetValue = hDelta * (offset) * 0.01; + + // + upperHBuffer[barIndex] = upperHValue - hOffsetValue; + lowerHBuffer[barIndex] = lowerHValue + hOffsetValue; + + // + // LOW ... + + // + double upperLValue = low[ArrayMaximum(low, barIndex - length + 1, length)]; + double lowerLValue = low[ArrayMinimum(low, barIndex - length + 1, length)]; + + // + double lDelta = MathAbs(upperLValue - lowerLValue); + double lOffsetValue = lDelta * (offset) * 0.01; + + // + upperLBuffer[barIndex] = upperLValue - lOffsetValue; + lowerLBuffer[barIndex] = lowerLValue + lOffsetValue; + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = length >= 7; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Open ... + ENUM_DRAW_TYPE openDrawType = showOpen ? DRAW_LINE : DRAW_NONE; + + // + // UPPER ... + SetIndexBuffer(upperOBufferIndex, upperOBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperOBufferIndex, PLOT_SHOW_DATA, showOpen); + PlotIndexSetDouble(upperOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(upperOBufferIndex, PLOT_DRAW_TYPE, openDrawType); + + // + // LOWER ... + SetIndexBuffer(lowerOBufferIndex, lowerOBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerOBufferIndex, PLOT_SHOW_DATA, showOpen); + PlotIndexSetDouble(lowerOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(lowerOBufferIndex, PLOT_DRAW_TYPE, openDrawType); + + // + // Close ... + ENUM_DRAW_TYPE closeDrawType = showClose ? DRAW_LINE : DRAW_NONE; + + // + // UPPER ... + SetIndexBuffer(upperCBufferIndex, upperCBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperCBufferIndex, PLOT_SHOW_DATA, showClose); + PlotIndexSetDouble(upperCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(upperCBufferIndex, PLOT_DRAW_TYPE, closeDrawType); + + // + // LOWER ... + SetIndexBuffer(lowerCBufferIndex, lowerCBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerCBufferIndex, PLOT_SHOW_DATA, showClose); + PlotIndexSetDouble(lowerCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(lowerCBufferIndex, PLOT_DRAW_TYPE, closeDrawType); + + // + // High ... + ENUM_DRAW_TYPE highDrawType = showHigh ? DRAW_LINE : DRAW_NONE; + + // + // UPPER ... + SetIndexBuffer(upperHBufferIndex, upperHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperHBufferIndex, PLOT_SHOW_DATA, showHigh); + PlotIndexSetDouble(upperHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(upperHBufferIndex, PLOT_DRAW_TYPE, highDrawType); + + // + // LOWER ... + SetIndexBuffer(lowerHBufferIndex, lowerHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerHBufferIndex, PLOT_SHOW_DATA, showHigh); + PlotIndexSetDouble(lowerHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(lowerHBufferIndex, PLOT_DRAW_TYPE, highDrawType); + + // + // Low ... + ENUM_DRAW_TYPE lowDrawType = showLow ? DRAW_LINE : DRAW_NONE; + + // + // UPPER ... + SetIndexBuffer(upperLBufferIndex, upperLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperLBufferIndex, PLOT_SHOW_DATA, showLow); + PlotIndexSetDouble(upperLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(upperLBufferIndex, PLOT_DRAW_TYPE, lowDrawType); + + // + // LOWER ... + SetIndexBuffer(lowerLBufferIndex, lowerLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerLBufferIndex, PLOT_SHOW_DATA, showLow); + PlotIndexSetDouble(lowerLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(lowerLBufferIndex, PLOT_DRAW_TYPE, lowDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.mq5 new file mode 100644 index 0000000..44f2c4d --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.mq5 @@ -0,0 +1,309 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator +// --------------------------------------------- +// Name: XFI +// Description: Price Momentum Power Detection +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFI Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XFI" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Length +input ENUM_MA_METHOD method = MODE_SMA; // MA Method +input ENUM_APPLIED_VOLUME appliedTo = VOLUME_TICK; // Applied To +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +// #property indicator_separate_window +#property indicator_chart_window + +// +#property indicator_buffers 2 +// #property indicator_plots 1 +#property indicator_plots 0 + +// +// FI Buffer ... +#define fiBufferIndex 0 +#define fiColorBufferIndex 1 + +// +double fiBuffer[]; +double fiColorBuffer[]; + +// +// #property indicator_label1 "XFI" +// #property indicator_type1 DRAW_COLOR_LINE +// #property indicator_color1 clrAqua, clrGray, clrFuchsia +// #property indicator_style1 STYLE_DOT +// #property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int fiHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + fiHandler = iForce( + _Symbol, + _Period, + length, + method, + appliedTo); + if (fiHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(fiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + // Check Calculated Bars ... + int fiCalculatedBars = BarsCalculated(fiHandler); + if (fiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFis = CopyBuffer(fiHandler, 0, 0, limit, fiBuffer); + if (copiedFis <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string fiBufferLabel = "XFI " + "(" + (string)length + ")"; + + // + // FI Buffer ... + ArraySetAsSeries(fiBuffer, true); + SetIndexBuffer(fiBufferIndex, fiBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(fiBufferIndex, fiBuffer, INDICATOR_DATA); + // PlotIndexSetString(fiBufferIndex, PLOT_LABEL, fiBufferLabel); + + // // + // // FI Color Buffer ... + ArraySetAsSeries(fiColorBuffer, true); + // SetIndexBuffer(fiColorBufferIndex, fiColorBuffer, INDICATOR_COLOR_INDEX); + SetIndexBuffer(fiColorBufferIndex, fiColorBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + double iValue = fiBuffer[bar_index]; + + // + double iColorIndex = + iValue > 0 ? 0 : iValue < 0 ? 2 + : 1; + + // + // Set Buffer Color Index ... + fiColorBuffer[bar_index] = iColorIndex; +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.osc.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.osc.mq5 new file mode 100644 index 0000000..0e7edc5 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xfi.osc.mq5 @@ -0,0 +1,309 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator +// --------------------------------------------- +// Name: XFI +// Description: Price Momentum Power Detection +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFI Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XFI" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Length +input ENUM_MA_METHOD method = MODE_SMA; // MA Method +input ENUM_APPLIED_VOLUME appliedTo = VOLUME_TICK; // Applied To +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window +// #property indicator_chart_window + +// +#property indicator_buffers 2 +#property indicator_plots 1 +// #property indicator_plots 0 + +// +// FI Buffer ... +#define fiBufferIndex 0 +#define fiColorBufferIndex 1 + +// +double fiBuffer[]; +double fiColorBuffer[]; + +// +#property indicator_label1 "XFI" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, clrGray, clrFuchsia +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int fiHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + fiHandler = iForce( + _Symbol, + _Period, + length, + method, + appliedTo); + if (fiHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(fiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + // Check Calculated Bars ... + int fiCalculatedBars = BarsCalculated(fiHandler); + if (fiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFis = CopyBuffer(fiHandler, 0, 0, limit, fiBuffer); + if (copiedFis <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string fiBufferLabel = "XFI " + "(" + (string)length + ")"; + + // + // FI Buffer ... + ArraySetAsSeries(fiBuffer, true); + // SetIndexBuffer(fiBufferIndex, fiBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(fiBufferIndex, fiBuffer, INDICATOR_DATA); + PlotIndexSetString(fiBufferIndex, PLOT_LABEL, fiBufferLabel); + + // + // FI Color Buffer ... + ArraySetAsSeries(fiColorBuffer, true); + SetIndexBuffer(fiColorBufferIndex, fiColorBuffer, INDICATOR_COLOR_INDEX); + // SetIndexBuffer(fiColorBufferIndex, fiColorBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + double iValue = fiBuffer[bar_index]; + + // + double iColorIndex = + iValue > 0 ? 0 : iValue < 0 ? 2 + : 1; + + // + // Set Buffer Color Index ... + fiColorBuffer[bar_index] = iColorIndex; +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhk.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhk.mq5 new file mode 100644 index 0000000..37cf4b5 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhk.mq5 @@ -0,0 +1,479 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------------- +// Name: XHK +// Description: Hiken Ashi ... +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XHK Indicator" +#property strict + +// +// Constants ... + +// +// Indicator Short Name ... +#define ShortName "XHK" + +// +// Imports ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; +input int smoothingLength = 17; // Smoothing Length +// +input group "Presentation"; +input bool drawHikenAshi = true; // Draw Hiken Ashi +input bool drawSmoothedHikenAshi = true; // Draw Smoothed Hiken Ashi + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 10 +#property indicator_plots 10 + +// +// Buffers ... + +// +// Open ... +#define openBufferIndex 0 +double openBuffer[]; + +// +// High ... +#define highBufferIndex 1 +double highBuffer[]; + +// +// Low ... +#define lowBufferIndex 2 +double lowBuffer[]; + +// +// Close ... +#define closeBufferIndex 3 +double closeBuffer[]; + +// +// Candle Color ... +#define candleColorBufferIndex 4 +double candleColorBuffer[]; + +// +#define candlesBufferIndex 0 + +// +#property indicator_label1 "XHK Open;XHK High;XHK Low;XHK Close" +#property indicator_type1 DRAW_COLOR_CANDLES +#property indicator_color1 CLR_NONE, clrAqua, clrMagenta + +// +// SM Open ... +#define openSMBufferIndex 5 +double openSMBuffer[]; + +// +// SM High ... +#define highSMBufferIndex 6 +double highSMBuffer[]; + +// +// SM Low ... +#define lowSMBufferIndex 7 +double lowSMBuffer[]; + +// +// SM Close ... +#define closeSMBufferIndex 8 +double closeSMBuffer[]; + +// +// SM Candle Color ... +#define candleColorSMBufferIndex 9 +double candleColorSMBuffer[]; + +// +#define candlesSMBufferIndex 1 + +// +#property indicator_label2 "XSMHK Open;XSMHK High;XSMHK Low;XSMHK Close" +#property indicator_type2 DRAW_COLOR_CANDLES +#property indicator_color2 CLR_NONE, clrDarkGreen, clrDarkRed + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +double mHideColorIDX = 0; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, prev_calculated, rates_total, open, high, close, low); + } + + // + CalculateSM(rates_total, prev_calculated); + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Candles Color ... + ArraySetAsSeries(candleColorBuffer, true); + SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(candleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(openBuffer, true); + PlotIndexSetInteger(openBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(highBuffer, true); + SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(closeBuffer, true); + SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(lowBuffer, true); + SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowBufferIndex, PLOT_SHOW_DATA, false); + + // + // Candles Color ... + ArraySetAsSeries(candleColorSMBuffer, true); + SetIndexBuffer(candleColorSMBufferIndex, candleColorSMBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(candlesSMBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(candlesSMBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(candleColorSMBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(openSMBuffer, true); + PlotIndexSetInteger(openSMBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(openSMBufferIndex, openSMBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(highSMBuffer, true); + SetIndexBuffer(highSMBufferIndex, highSMBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highSMBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(closeSMBuffer, true); + SetIndexBuffer(closeSMBufferIndex, closeSMBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeSMBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(lowSMBuffer, true); + SetIndexBuffer(lowSMBufferIndex, lowSMBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowSMBufferIndex, PLOT_SHOW_DATA, false); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[] // +) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = openBuffer[bar_index + 1]; + mPrevHKCloseValue = closeBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + openBuffer[bar_index] = mHKOpenValue; + highBuffer[bar_index] = mHKHighValue; + lowBuffer[bar_index] = mHKLowValue; + closeBuffer[bar_index] = mHKCloseValue; + + // + bool isBearish = + // + openBuffer[bar_index] > closeBuffer[bar_index] + // + ; + + // + candleColorBuffer[bar_index] = !drawHikenAshi + ? mHideColorIDX + : isBearish + ? 2 + : 1; +} + +// +// Calculate Smoothed HikenAshi ... +void CalculateSM( + int ratesTotal, // Total Bars + int prevCalculated // Calculated Bars +) +{ + // + // Open ... + int calculatedSMHKOpens = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + smoothingLength, + openBuffer, + openSMBuffer); + + // + // High ... + int calculatedSMHKHighs = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + smoothingLength, + highBuffer, + highSMBuffer); + + // + // Low ... + int calculatedSMHKLows = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + smoothingLength, + lowBuffer, + lowSMBuffer); + + // + // Close ... + int calculatedSMHKCloses = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + smoothingLength, + closeBuffer, + closeSMBuffer); + + // + // Find Calculated Items for Colors ... + int mNumberOfItems = MathMin(calculatedSMHKOpens, calculatedSMHKHighs); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMHKLows); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMHKCloses); + + // + // Create a Loop for Color of Candles ... + for (int i = 0; i < mNumberOfItems; i++) + { + // + bool isBearish = + // + openSMBuffer[i] > closeSMBuffer[i] + // + ; + + // + if (drawSmoothedHikenAshi) + { + // + candleColorSMBuffer[i] = isBearish + ? 2 + : 1; + } + else + { + // + candleColorSMBuffer[i] = mHideColorIDX; + } + } +} diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhull.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhull.mq5 new file mode 100644 index 0000000..ffc1792 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xhull.mq5 @@ -0,0 +1,583 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XHULL +// Description: Hull Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XHULL Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XHULL" + +// +struct XHullData +{ + // + double value; + double value3; + + // + double wsum1; + double wsum2; + double wsum3; + + // + double lsum1; + double lsum2; + double lsum3; +}; + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init( + int mPeriod, + double mDivisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(mPeriod > 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 72; // Length +input double divisor = 2.0; // Divisor (Speed) + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showUpZone = true; // Show Up Zone +input bool showDownZone = true; // Show Down Zone + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// UP Zone ... + +// +#define upZoneBufferIndex 0 +#define upZoneColorBufferIndex 1 + +// +double upZoneBuffer[]; +double upZoneColorBuffer[]; + +// +#property indicator_label1 "XHULL Up" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLightGray, clrAqua, clrMagenta +#property indicator_width1 1 + +// +// DOWN Zone ... + +// +#define downZoneBufferIndex 2 +#define downZoneColorBufferIndex 3 + +// +double downZoneBuffer[]; +double downZoneColorBuffer[]; + +// +#property indicator_label2 "XHULL Down" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrLightGray, clrAqua, clrMagenta +#property indicator_width2 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + length, + divisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + length, + divisor); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart mPeriod is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + delete mUpZHull; + delete mDownZHull; +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = getPrice( + upAppliedTo, + open, high, low, close, i); + + // + double downPrice = getPrice( + downAppliedTo, + open, high, low, close, i); + + // + CalculateBuffers( + i, + rates_total, + upPrice, + downPrice); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + divisor >= 0.5; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE upZoneDrawType = showUpZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(upZoneBufferIndex, upZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_SHOW_DATA, showUpZone); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_DRAW_TYPE, upZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(upZoneColorBufferIndex, upZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE downZoneDrawType = showDownZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(downZoneBufferIndex, downZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_SHOW_DATA, showDownZone); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_DRAW_TYPE, downZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(downZoneColorBufferIndex, downZoneColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + upZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (upZoneBuffer[bar_index] > upZoneBuffer[bar_index - 1]) + ? 1 + : (upZoneBuffer[bar_index] < upZoneBuffer[bar_index - 1]) + ? 2 + : upZoneColorBuffer[bar_index - 1] + : 0; + upZoneColorBuffer[bar_index] = upColorIDX; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + downZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (downZoneBuffer[bar_index] > downZoneBuffer[bar_index - 1]) + ? 1 + : (downZoneBuffer[bar_index] < downZoneBuffer[bar_index - 1]) + ? 2 + : downZoneColorBuffer[bar_index - 1] + : 0; + downZoneColorBuffer[bar_index] = downColorIDX; +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xich.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xich.mq5 new file mode 100644 index 0000000..00bf6fb --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xich.mq5 @@ -0,0 +1,846 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XICH +// Description: Ichimoku Kinko Hyo ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XICH Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XICH" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ICHIMOKU Kinko Hyo ... + +// +// TENKANSEN ... +input group "Tenkan Sen"; +input int tenkanSenLength = 9; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// KIJUNSEN ... +input group "Kijun Sen"; +input int kijunSenLength = 26; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// SENKOUSPANB ... +input group "Senkou Span B"; +input int senkouSpanBLength = 52; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// CHIKOUSPAN ... +input group "Chikou Span"; +input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type + +// +input group "Presentation"; +input bool showTenkanSen = true; // Show Tenkan Sen +input bool showKijunSen = true; // Show Kijun Sen +input bool showKijunSenPlus = false; // Show Kijun Sen + +input bool showKijunSenNegative = false; // Show Kijun Sen - +input bool showChikouSpan = true; // Show Chikou Span +input bool showSenkouSpanA = true; // Show Senkou Span A +input bool showSenkouSpanB = true; // Show Senkou Span B +input bool showKumo = true; // Show Kumo +input bool shiftKumo = true; // Shift Kumo to Future + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 8 + +// +// PLOTTED Buffers ... + +// +// ICHIMOKU ... + +// +// TENKANSEN ... + +// +#define tenkanSenBufferIndex 0 +double tenkanSenBuffer[]; + +// +#property indicator_label1 "XICH TK" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// KIJUNSEN ... + +// +#define kijunSenBufferIndex 1 +double kijunSenBuffer[]; + +// +#property indicator_label2 "XICH KJ" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDodgerBlue +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#define kijunSenPlusBufferIndex 2 +double kijunSenPlusBuffer[]; + +// +#property indicator_label3 "XICH KJ+" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMediumTurquoise +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define kijunSenNegativeBufferIndex 3 +double kijunSenNegativeBuffer[]; + +// +#property indicator_label4 "XICH KJ-" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrDarkSeaGreen +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CHIKOUSPAN ... + +// +#define chikouSpanBufferIndex 4 +double chikouSpanBuffer[]; + +// +#property indicator_label5 "XICH CS" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrDarkGreen +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +#define senkouABufferIndex 5 +double senkouABuffer[]; + +// +#property indicator_label6 "XICH SSA" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGray +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +#define senkouBBufferIndex 6 +double senkouBBuffer[]; + +// +#property indicator_label7 "XICH SSB" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// KUMO ... + +// +// SENKOUSPANA ... + +// +#define senkouSpanABufferIndex 7 +double senkouSpanABuffer[]; + +// +// SENKOUSPANB ... + +// +#define senkouSpanBBufferIndex 8 +double senkouSpanBBuffer[]; + +// +// KUMOCLOUD ... + +// +#define kumoBufferIndex 7 + +// +#property indicator_label8 "XICH Kumo" +#property indicator_type8 DRAW_FILLING +#property indicator_color8 clrAqua, clrMagenta +#property indicator_style8 STYLE_SOLID +#property indicator_width8 1 + +// +// DATA Buffers ... + +// +#define dTenkanBufferIndex 9 +double dTenkanBuffer[]; + +// +#define dKijunBufferIndex 10 +double dKijunBuffer[]; + +// +#define dChikouBufferIndex 11 +double dChikouBuffer[]; + +// +#define dSSABufferIndex 12 +double dSSABuffer[]; + +// +#define dSSBBufferIndex 13 +double dSSBBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; +int mHandler; + +// +ENUM_SERIESMODE mTenkanSenTopMode = NULL; +ENUM_SERIESMODE mTenkanSenBottomMode = NULL; + +// +ENUM_SERIESMODE mKijunSenTopMode = NULL; +ENUM_SERIESMODE mKijunSenBottomMode = NULL; + +// +ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; +ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Init Handler ... + mHandler = iIchimoku( + _Symbol, + _Period, + tenkanSenLength, + kijunSenLength, + senkouSpanBLength); + if (mHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + IndicatorRelease(mHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int ichCalculatedBars = BarsCalculated(mHandler); + if (ichCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer); + int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer); + int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer); + int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer); + int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer); + if ( + copiedSSAs < 0 || + copiedSSBs < 0 || + copiedKijuns < 0 || + copiedTenkans < 0 || + copiedChikous < 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ichimoku ... + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // ICHIMOKU ... + + // + // TENKANSEN ... + + // + ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType); + + // + // KIJUNSEN ... + + // + ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenBuffer, true); + SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType); + + // + // KIJUNSEN Plus ... + + // + ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenPlusBuffer, true); + SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType); + + // + // KIJUNSEN Negative ... + + // + ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenNegativeBuffer, true); + SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType); + + // + // CHIKOUSPAN ... + + // + ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(chikouSpanBuffer, true); + SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType); + + // + // SENKOUSPAN A and B ... + int shiftSize = shiftKumo ? kijunSenLength : 0; + + // + // SENKOUSPANA ... + ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouABuffer, true); + SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); + + // + // SENKOUSPANB ... + ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouBBuffer, true); + SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); + + // + // KUMO ... + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // KUMO ... + + // + ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; + + // + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType); + + // + // DATA Buffers ... + + // + // D Tenkan ... + ArraySetAsSeries(dTenkanBuffer, true); + SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS); + + // + // D Kijun ... + ArraySetAsSeries(dKijunBuffer, true); + SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS); + + // + // D Chikou ... + ArraySetAsSeries(dChikouBuffer, true); + SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS); + + // + // D SSA ... + ArraySetAsSeries(dSSABuffer, true); + SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS); + + // + // D SSB ... + ArraySetAsSeries(dSSBBuffer, true); + SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // ICHIMOKU ... + + // + double topValue; + double bottomValue; + + // + // TENKANSEN ... + + // + // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... + if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) + { + // + switch (tenkanSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mTenkanSenTopMode = MODE_HIGH; + mTenkanSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mTenkanSenTopMode = MODE_OPEN; + mTenkanSenBottomMode = MODE_CLOSE; + break; + } + } + + // + XOHCL bar; + bar.Init( + _Symbol, + _Period, + bar_index + // + ); + + // + // Calculate Top ... + topValue = bar + .FindHighest( + tenkanSenLength, + mTenkanSenTopMode + // + ); + + // + // Calculate Bottom ... + bottomValue = bar + .FindLowest( + tenkanSenLength, + mTenkanSenBottomMode + // + ); + + // + double tenkanSenValue = (topValue + bottomValue) / 2; + tenkanSenBuffer[bar_index] = tenkanSenValue; + + // + // KIJUNSEN ... + + // + // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... + if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) + { + // + switch (kijunSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mKijunSenTopMode = MODE_HIGH; + mKijunSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mKijunSenTopMode = MODE_OPEN; + mKijunSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = bar + .FindHighest( + kijunSenLength, + mKijunSenTopMode + // + ); + + // + // Calculate Bottom ... + bottomValue = bar + .FindLowest( + kijunSenLength, + mKijunSenBottomMode + // + ); + + // + double kijunSenValue = (topValue + bottomValue) / 2; + kijunSenBuffer[bar_index] = kijunSenValue; + + // + kijunSenPlusBuffer[bar_index] = kijunSenValue; + kijunSenNegativeBuffer[bar_index] = kijunSenValue; + + // + // CHIKOUSPAN ... + double chikouSpanValue = bar + .GetPrice(chikuoSpanAppliedTo); + + // + chikouSpanBuffer[bar_index] = chikouSpanValue; + + // + // KUMO ... + + // + // SENKOUSPANA ... + double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; + senkouABuffer[bar_index] = senkouSpanAValue; + senkouSpanABuffer[bar_index] = senkouSpanAValue; + + // + // SENKOUSPANB ... + + // + // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... + if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) + { + // + switch (senkouSpanBMode) + { + // + case X_XICH_HH_LL_MODE: + // + mSenkouSpanBTopMode = MODE_HIGH; + mSenkouSpanBBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mSenkouSpanBTopMode = MODE_OPEN; + mSenkouSpanBBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = bar + .FindHighest( + senkouSpanBLength, + mSenkouSpanBTopMode + // + ); + + // + // Calculate Bottom ... + bottomValue = bar + .FindLowest( + senkouSpanBLength, + mSenkouSpanBBottomMode + // + ); + + // + double senkouSpanBValue = (topValue + bottomValue) / 2; + senkouBBuffer[bar_index] = senkouSpanBValue; + senkouSpanBBuffer[bar_index] = senkouSpanBValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xlh.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xlh.mq5 new file mode 100644 index 0000000..e06de55 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xlh.mq5 @@ -0,0 +1,352 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XLH Indicator +// --------------------------------------------- +// Name: XLH +// Description: Moving Average Indicator +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XLH Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XLH" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 14; // Length +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// HH Buffer ... +#define hhBufferIndex 0 + +// +double hhBuffer[]; + +// +#property indicator_label1 "XLH HH" +#property indicator_type1 DRAW_LINE +#property indicator_color1 CLR_NONE, // clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// LL Buffer ... +#define llBufferIndex 1 + +// +double llBuffer[]; + +// +#property indicator_label2 "XLH LL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 CLR_NONE, // clrFuchsia +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Signal Buffer ... +#define signalBufferIndex 2 + +// +double signalBuffer[]; + +// +#property indicator_label3 "XLH S" +#property indicator_type3 DRAW_LINE +#property indicator_color3 CLR_NONE, // clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // HH Buffer ... + string hhBufferLabel = ShortName + " HH " + "(" + (string)length + ")"; + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hhBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(hhBufferIndex, PLOT_LABEL, hhBufferLabel); + + // + // LL Buffer ... + string llBufferLabel = ShortName + " LL " + "(" + (string)length + ")"; + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + PlotIndexSetInteger(llBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(llBufferIndex, PLOT_LABEL, llBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + " S " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Threshold ... + // + // HH Buffer ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + length, + bar_index + // + ); + XOHCL hhBar; + hhBar.Init( + _Symbol, + _Period, + hhIndex + // + ); + double hhValue = hhBar.GetPrice(hhMode); + + // + hhBuffer[bar_index] = hhValue; + + // + // LL Buffer ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + length, + bar_index + // + ); + XOHCL llBar; + llBar.Init( + _Symbol, + _Period, + llIndex + // + ); + double llValue = llBar.GetPrice(llMode); + + // + llBuffer[bar_index] = llValue; + + // + double lhDiff = hhValue - llValue; + double signalValue = (lhDiff / 2); + + // + signalBuffer[bar_index] = (hhValue - signalValue); +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmc.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmc.mq5 new file mode 100644 index 0000000..f7fe43b --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmc.mq5 @@ -0,0 +1,446 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XMC MA Cross Indicator +// --------------------------------------------------- +// Name: XMC +// Description: Moving Average Crosses +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XMC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XMC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Fast"; +input int fastMaLength = 9; // Length +input int fastMaShift = 0; // Shift +input ENUM_MA_METHOD fastMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE fastMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Slow"; +input int slowMaLength = 18; // Length +input int slowMaShift = 0; // Shift +input ENUM_MA_METHOD slowMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE slowMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Verifier"; +input int verifierMaLength = 50; // Length +input int verifierMaShift = 0; // Shift +input ENUM_MA_METHOD verifierMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE verifierMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showVerifierMa = true; // Show Verifier + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "XMC MA F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrYellow +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "XMC MA S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDarkOrange +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// VERIFIER ... +#define verifierMaBufferIndex 2 +double verifierMaBuffer[]; + +// +#property indicator_label3 "XMC MA V" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrDarkBlue +#property indicator_style3 STYLE_SOLID +#property indicator_width3 2 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fastMaHandler = INVALID_HANDLE; +int slowMaHandler = INVALID_HANDLE; +int verifierMaHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // MA Initialization ... + + // + // FAST ... + fastMaHandler = iMA( + _Symbol, + _Period, + fastMaLength, + fastMaShift, + fastMaMethod, + fastMaAppliedTo); + if (fastMaHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // SLOW ... + slowMaHandler = iMA( + _Symbol, + _Period, + slowMaLength, + slowMaShift, + slowMaMethod, + slowMaAppliedTo); + if (slowMaHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // VERIFIER ... + verifierMaHandler = iMA( + _Symbol, + _Period, + verifierMaLength, + verifierMaShift, + verifierMaMethod, + verifierMaAppliedTo); + if (verifierMaHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(fastMaHandler); + IndicatorRelease(slowMaHandler); + IndicatorRelease(verifierMaHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int fastMaCalculatedBars = BarsCalculated(fastMaHandler); + int slowMaCalculatedBars = BarsCalculated(slowMaHandler); + int verifierMaCalculatedBars = BarsCalculated(verifierMaHandler); + if (fastMaCalculatedBars < maxLength || + slowMaCalculatedBars < maxLength || + verifierMaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFastMas = CopyBuffer(fastMaHandler, 0, 0, limit, fastMaBuffer); + int copiedSlowMas = CopyBuffer(slowMaHandler, 0, 0, limit, slowMaBuffer); + int copiedVerifierMas = CopyBuffer(verifierMaHandler, 0, 0, limit, verifierMaBuffer); + if (copiedFastMas <= 0 || + copiedSlowMas <= 0 || + copiedVerifierMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + // Validate Ma ... + (fastMaLength > 2 && + slowMaLength > fastMaLength && + verifierMaLength > slowMaLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + result = MathMax(result, fastMaLength); + result = MathMax(result, slowMaLength); + result = MathMax(result, verifierMaLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // MA ... + + // + // FAST ... + ENUM_DRAW_TYPE fastMaDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastMaDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowMaDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowMaDrawType); + + // + // VERIFIER ... + ENUM_DRAW_TYPE verifierMaDrawType = showVerifierMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(verifierMaBuffer, true); + SetIndexBuffer(verifierMaBufferIndex, verifierMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_TYPE, verifierMaDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmrb.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmrb.mq5 new file mode 100644 index 0000000..5ff1d82 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xmrb.mq5 @@ -0,0 +1,855 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------- +// Name: XMRB +// Description: Moving Average Ribbon +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XMRB Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XMRB" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Ribbon 1"; +input int fast1Length = 20; // Fast +input int slow1Length = 50; // Slow +input ENUM_APPLIED_PRICE r1AppliedTo = PRICE_HIGH; // Applied To + +// +input group "Ribbon 2"; +input int fast2Length = 20; // Fast +input int slow2Length = 50; // Slow +input ENUM_APPLIED_PRICE r2AppliedTo = PRICE_OPEN; // Applied To + +// +input group "Ribbon 3"; +input int fast3Length = 20; // Fast +input int slow3Length = 50; // Slow +input ENUM_APPLIED_PRICE r3AppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Ribbon 4"; +input int fast4Length = 20; // Fast +input int slow4Length = 50; // Slow +input ENUM_APPLIED_PRICE r4AppliedTo = PRICE_MEDIAN; // Applied To + +// +input group "Ribbon 5"; +input int fast5Length = 20; // Fast +input int slow5Length = 50; // Slow +input ENUM_APPLIED_PRICE r5AppliedTo = PRICE_TYPICAL; // Applied To + +// +input group "Ribbon 6"; +input int fast6Length = 20; // Fast +input int slow6Length = 50; // Slow +input ENUM_APPLIED_PRICE r6AppliedTo = PRICE_LOW; // Applied To + +// +input group "Calculation"; +input ENUM_MA_METHOD ribbonMode = MODE_EMA; // Mode + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showRibbon = false; // Show Ribbon + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 14 +#property indicator_plots 14 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "XMRB F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "XMRB S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +// FAST ... + +// +#define fast1BufferIndex 2 +double fast1Buffer[]; + +// +#property indicator_label3 "XMRB 1 F" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAquamarine +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define fast2BufferIndex 3 +double fast2Buffer[]; + +// +#property indicator_label4 "XMRB 2 F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrAquamarine +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define fast3BufferIndex 4 +double fast3Buffer[]; + +// +#property indicator_label5 "XMRB 3 F" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +#define fast4BufferIndex 5 +double fast4Buffer[]; + +// +#property indicator_label6 "XMRB 4 F" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +#define fast5BufferIndex 6 +double fast5Buffer[]; + +// +#property indicator_label7 "XMRB 5 F" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrAquamarine +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +#define fast6BufferIndex 7 +double fast6Buffer[]; + +// +#property indicator_label8 "XMRB 6 F" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrAquamarine +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +// SLOW ... + +// +#define slow1BufferIndex 8 +double slow1Buffer[]; + +// +#property indicator_label9 "XMRB 1 S" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrPlum +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define slow2BufferIndex 9 +double slow2Buffer[]; + +// +#property indicator_label10 "XMRB 2 S" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrPlum +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define slow3BufferIndex 10 +double slow3Buffer[]; + +// +#property indicator_label11 "XMRB 3 S" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrPlum +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define slow4BufferIndex 11 +double slow4Buffer[]; + +// +#property indicator_label12 "XMRB 4 S" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrPlum +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define slow5BufferIndex 12 +double slow5Buffer[]; + +// +#property indicator_label13 "XMRB 5 S" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrPlum +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define slow6BufferIndex 13 +double slow6Buffer[]; + +// +#property indicator_label14 "XMRB 6 S" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrPlum +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fast1MaHandler = INVALID_HANDLE; +int fast2MaHandler = INVALID_HANDLE; +int fast3MaHandler = INVALID_HANDLE; +int fast4MaHandler = INVALID_HANDLE; +int fast5MaHandler = INVALID_HANDLE; +int fast6MaHandler = INVALID_HANDLE; + +// +int slow1MaHandler = INVALID_HANDLE; +int slow2MaHandler = INVALID_HANDLE; +int slow3MaHandler = INVALID_HANDLE; +int slow4MaHandler = INVALID_HANDLE; +int slow5MaHandler = INVALID_HANDLE; +int slow6MaHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize MAs ... + if (!InitializeMas()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(fast1MaHandler); + IndicatorRelease(fast2MaHandler); + IndicatorRelease(fast3MaHandler); + IndicatorRelease(fast4MaHandler); + IndicatorRelease(fast5MaHandler); + IndicatorRelease(fast6MaHandler); + + // + IndicatorRelease(slow1MaHandler); + IndicatorRelease(slow2MaHandler); + IndicatorRelease(slow3MaHandler); + IndicatorRelease(slow4MaHandler); + IndicatorRelease(slow5MaHandler); + IndicatorRelease(slow6MaHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + // + int fast1MaCalculatedBars = BarsCalculated(fast1MaHandler); + int fast2MaCalculatedBars = BarsCalculated(fast2MaHandler); + int fast3MaCalculatedBars = BarsCalculated(fast3MaHandler); + int fast4MaCalculatedBars = BarsCalculated(fast4MaHandler); + int fast5MaCalculatedBars = BarsCalculated(fast5MaHandler); + int fast6MaCalculatedBars = BarsCalculated(fast6MaHandler); + // + int slow1MaCalculatedBars = BarsCalculated(slow1MaHandler); + int slow2MaCalculatedBars = BarsCalculated(slow2MaHandler); + int slow3MaCalculatedBars = BarsCalculated(slow3MaHandler); + int slow4MaCalculatedBars = BarsCalculated(slow4MaHandler); + int slow5MaCalculatedBars = BarsCalculated(slow5MaHandler); + int slow6MaCalculatedBars = BarsCalculated(slow6MaHandler); + if ( + fast1MaCalculatedBars < maxLength || + fast2MaCalculatedBars < maxLength || + fast3MaCalculatedBars < maxLength || + fast4MaCalculatedBars < maxLength || + fast5MaCalculatedBars < maxLength || + fast6MaCalculatedBars < maxLength || + slow1MaCalculatedBars < maxLength || + slow2MaCalculatedBars < maxLength || + slow3MaCalculatedBars < maxLength || + slow4MaCalculatedBars < maxLength || + slow5MaCalculatedBars < maxLength || + slow6MaCalculatedBars < maxLength // + ) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + // + int copiedFast1Mas = CopyBuffer(fast1MaHandler, 0, 0, limit, fast1Buffer); + int copiedFast2Mas = CopyBuffer(fast2MaHandler, 0, 0, limit, fast2Buffer); + int copiedFast3Mas = CopyBuffer(fast3MaHandler, 0, 0, limit, fast3Buffer); + int copiedFast4Mas = CopyBuffer(fast4MaHandler, 0, 0, limit, fast4Buffer); + int copiedFast5Mas = CopyBuffer(fast5MaHandler, 0, 0, limit, fast5Buffer); + int copiedFast6Mas = CopyBuffer(fast6MaHandler, 0, 0, limit, fast6Buffer); + // + int copiedSlow1Mas = CopyBuffer(slow1MaHandler, 0, 0, limit, slow1Buffer); + int copiedSlow2Mas = CopyBuffer(slow2MaHandler, 0, 0, limit, slow2Buffer); + int copiedSlow3Mas = CopyBuffer(slow3MaHandler, 0, 0, limit, slow3Buffer); + int copiedSlow4Mas = CopyBuffer(slow4MaHandler, 0, 0, limit, slow4Buffer); + int copiedSlow5Mas = CopyBuffer(slow5MaHandler, 0, 0, limit, slow5Buffer); + int copiedSlow6Mas = CopyBuffer(slow6MaHandler, 0, 0, limit, slow6Buffer); + if ( + copiedFast1Mas <= 0 || + copiedFast2Mas <= 0 || + copiedFast3Mas <= 0 || + copiedFast4Mas <= 0 || + copiedFast5Mas <= 0 || + copiedFast6Mas <= 0 || + copiedSlow1Mas <= 0 || + copiedSlow2Mas <= 0 || + copiedSlow3Mas <= 0 || + copiedSlow4Mas <= 0 || + copiedSlow5Mas <= 0 || + copiedSlow6Mas <= 0 // + ) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (fast1Length > 2 && + fast2Length > 2 && + fast3Length > 2 && + fast4Length > 2 && + fast5Length > 2 && + fast6Length > 2 && + slow1Length > fast1Length && + slow2Length > fast2Length && + slow3Length > fast3Length && + slow4Length > fast4Length && + slow5Length > fast5Length && + slow6Length > fast6Length + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + + // + result = MathMax(fast1Length, fast2Length); + result = MathMax(result, fast3Length); + result = MathMax(result, fast4Length); + result = MathMax(result, fast5Length); + result = MathMax(result, fast6Length); + + // + result = MathMax(result, slow1Length); + result = MathMax(result, slow2Length); + result = MathMax(result, slow3Length); + result = MathMax(result, slow4Length); + result = MathMax(result, slow5Length); + result = MathMax(result, slow6Length); + + // + return result; +} + +// +// Initialize Ma Handlers ... +bool InitializeMas() +{ + // + bool result = false; + + // + fast1MaHandler = iMA( + _Symbol, + _Period, + fast1Length, + 0, + ribbonMode, + r1AppliedTo); + fast2MaHandler = iMA( + _Symbol, + _Period, + fast2Length, + 0, + ribbonMode, + r2AppliedTo); + fast3MaHandler = iMA( + _Symbol, + _Period, + fast3Length, + 0, + ribbonMode, + r3AppliedTo); + fast4MaHandler = iMA( + _Symbol, + _Period, + fast4Length, + 0, + ribbonMode, + r4AppliedTo); + fast5MaHandler = iMA( + _Symbol, + _Period, + fast5Length, + 0, + ribbonMode, + r5AppliedTo); + fast6MaHandler = iMA( + _Symbol, + _Period, + fast6Length, + 0, + ribbonMode, + r6AppliedTo); + + // + slow1MaHandler = iMA( + _Symbol, + _Period, + slow1Length, + 0, + ribbonMode, + r1AppliedTo); + slow2MaHandler = iMA( + _Symbol, + _Period, + slow2Length, + 0, + ribbonMode, + r2AppliedTo); + slow3MaHandler = iMA( + _Symbol, + _Period, + slow3Length, + 0, + ribbonMode, + r3AppliedTo); + slow4MaHandler = iMA( + _Symbol, + _Period, + slow4Length, + 0, + ribbonMode, + r4AppliedTo); + slow5MaHandler = iMA( + _Symbol, + _Period, + slow5Length, + 0, + ribbonMode, + r5AppliedTo); + slow6MaHandler = iMA( + _Symbol, + _Period, + slow6Length, + 0, + ribbonMode, + r6AppliedTo); + + // + result = + fast1MaHandler != INVALID_HANDLE && + fast2MaHandler != INVALID_HANDLE && + fast3MaHandler != INVALID_HANDLE && + fast4MaHandler != INVALID_HANDLE && + fast5MaHandler != INVALID_HANDLE && + fast6MaHandler != INVALID_HANDLE && + slow1MaHandler != INVALID_HANDLE && + slow2MaHandler != INVALID_HANDLE && + slow3MaHandler != INVALID_HANDLE && + slow4MaHandler != INVALID_HANDLE && + slow5MaHandler != INVALID_HANDLE && + slow6MaHandler != INVALID_HANDLE; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // FAST ... + ENUM_DRAW_TYPE fastDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, showFastMa); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, showSlowMa); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowDrawType); + + // + // DATA ... + ENUM_DRAW_TYPE ribbonDrawType = showRibbon ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(fast1Buffer, true); + SetIndexBuffer(fast1BufferIndex, fast1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast2Buffer, true); + SetIndexBuffer(fast2BufferIndex, fast2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast3Buffer, true); + SetIndexBuffer(fast3BufferIndex, fast3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast4Buffer, true); + SetIndexBuffer(fast4BufferIndex, fast4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast5Buffer, true); + SetIndexBuffer(fast5BufferIndex, fast5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast6Buffer, true); + SetIndexBuffer(fast6BufferIndex, fast6Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast6BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast6BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast6BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow1Buffer, true); + SetIndexBuffer(slow1BufferIndex, slow1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow2Buffer, true); + SetIndexBuffer(slow2BufferIndex, slow2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow3Buffer, true); + SetIndexBuffer(slow3BufferIndex, slow3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow4Buffer, true); + SetIndexBuffer(slow4BufferIndex, slow4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow5Buffer, true); + SetIndexBuffer(slow5BufferIndex, slow5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow6Buffer, true); + SetIndexBuffer(slow6BufferIndex, slow6Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow6BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow6BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow6BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Retireve Values ... + + // + double fast1Value = fast1Buffer[bar_index]; + double fast2Value = fast2Buffer[bar_index]; + double fast3Value = fast3Buffer[bar_index]; + double fast4Value = fast4Buffer[bar_index]; + double fast5Value = fast5Buffer[bar_index]; + double fast6Value = fast6Buffer[bar_index]; + + // + double fasts[] = { + fast1Value, + fast2Value, + fast3Value, + fast4Value, + fast5Value, + fast6Value}; + + // + double slow1Value = slow1Buffer[bar_index]; + double slow2Value = slow2Buffer[bar_index]; + double slow3Value = slow3Buffer[bar_index]; + double slow4Value = slow4Buffer[bar_index]; + double slow5Value = slow5Buffer[bar_index]; + double slow6Value = slow6Buffer[bar_index]; + + // + double slows[] = { + slow1Value, + slow2Value, + slow3Value, + slow4Value, + slow5Value, + slow6Value}; + + // + double fastValue = GetAverage(fasts); + fastMaBuffer[bar_index] = fastValue; + + // + double slowValue = GetAverage(slows); + slowMaBuffer[bar_index] = slowValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xobd.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xobd.mq5 new file mode 100644 index 0000000..2865679 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xobd.mq5 @@ -0,0 +1,392 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Indicator +// ----------------------------------------------------- +// Name: XOBD +// Description: detect Order Blocks based on Swings ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XOBD Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XOBD" +// +// END Constants ... +// + +// +// START Inputs ... +// +// +input int length = 5; // Swing Length + +// +input uchar swingHighArrowCode = 108; // Swing High Arrow Code +input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color + +// +input uchar swingLowArrowCode = 108; // Swing Low Arrow Code +input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color +// +// END Inputs ... +// + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Include Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 1 +#property indicator_plots 0 + +// +#define swingBufferIndex 0 +double swingBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length * 3); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ArraySetAsSeries(swingBuffer, true); + SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // GetCandleSwing(bar_index); + ENUM_X_SWING_TYPE type = X_NO_SWING; + + // + // Try To Detect Order Blocks ... + bool isSwingLow = false; + bool isSwingHigh = false; + + // + // Reading Candles Data ... + int start = bar_index; + int count = (length * 2) + 2; + int end = start + count; + XOHCL bars[]; + GetBars( + bars, + _Symbol, + _Period, + start, + count + // + ); + + // + // Swing Low ... + isSwingLow = + // + bars[1].close > bars[2].close && + bars[2].close > bars[3].close && + // + bars[3].close < bars[4].close && + // + bars[5].close > bars[4].close && + bars[6].close > bars[5].close + // + ; + + // + if (isSwingLow) + { + type = X_SWING_LOW; + } + + // + if (!isSwingLow) + { + // + // Swing High ... + isSwingHigh = + // + bars[1].close < bars[2].close && + bars[2].close < bars[3].close && + // + bars[3].close > bars[4].close && + // + bars[5].close < bars[4].close && + bars[6].close < bars[5].close + // + ; + + // + if (isSwingHigh) + { + type = X_SWING_HIGH; + } + } + + // + switch (type) + { + // + // Swing High ... + case X_SWING_HIGH: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(1, bar_index); + break; + + // + // Swinmg Low ... + case X_SWING_LOW: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(0, bar_index); + break; + + // + // No Swing ... + default: + case X_NO_SWING: + // + swingBuffer[bar_index] = 0; + break; + } +} + +// +// Draw a Swing Arrow Shape ... +void DrawSwingArrow( + int type, // Swing Type: 0 - Low / 1 - High ... + int bar_index // +) +{ + // + bool isSwingHigh = type == 1; + + // + if ((isSwingHigh && swingHighArrowCode == 0) || + (!isSwingHigh && swingLowArrowCode == 0)) + { + return; + } + + XOHCL candle; + candle.Init( + _Symbol, + _Period, + bar_index + 3); + double arrowDistanceInPoint = 0; + + // + // Define Required Object Properties fro Draw an Arrow ... + datetime time = iTime(_Symbol, _Period, bar_index + 3); + double purePrice = isSwingHigh ? candle.high : candle.low; + color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor; + ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP; + uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode); + double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint; + string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice; + + // + // Draw desired Arrow ... + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xosc.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xosc.mq5 new file mode 100644 index 0000000..ecf3a27 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xosc.mq5 @@ -0,0 +1,721 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XOSC +// Description: provides some oscillator values +// as empty Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XOSC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ATR ... +input group "ATR"; +input int atrLength = 14; // Length + +// +// RVI ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "RVI"; +input int rviLength = 10; // Length + +// +// BULLPOWER ... +input group "Bulls Power"; +input int bullpLength = 13; // Length + +// +// BEARPOWER ... +input group "Bears Power"; +input int bearpLength = 13; // Length + +// +// VOLUME ... +input group "Volumes"; +input ENUM_APPLIED_VOLUME volumeAppliedTo = VOLUME_TICK; // Applied To + +// +// RSI ... +input group "RSI"; +input int rsiLength = 14; // Length +input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // Applied To + +// +// CCI ... +input group "CCI"; +input int cciLength = 14; // Length +input ENUM_APPLIED_PRICE cciAppliedTo = PRICE_TYPICAL; // Applied To + +// +// STDDEV ... +input group "Standard Deviation"; +input int stddevLength = 20; // Length +input int stddevShift = 0; // Shift +input ENUM_MA_METHOD stddevMethod = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE stddevAppliedTo = PRICE_CLOSE; // AppliedTo + +// +// MOMENTUM ... +input group "Momentum"; +input int momentumLength = 14; // Length +input ENUM_APPLIED_PRICE momentumAppliedTo = PRICE_CLOSE; // Applied To + +// +// SAR ... +input group "SAR"; +input double sarStep = 0.02; // Step +input double sarMaximum = 0.2; // Maximum + +// +// MACD ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "MACD"; +input int macdFastLength = 12; // Fast Length +input int macdSlowLength = 26; // Slow Length +input int macdSignaLength = 9; // Signal Length +input ENUM_APPLIED_PRICE macdAppliedTo = PRICE_CLOSE; // Applied To + +// +// STOCHASTIC ... +// The buffer numbers: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "Stochastic"; +input int stochKLength = 5; // K Length +input int stochDLength = 3; // D Length +input int stochSlowing = 3; // Slowing +input ENUM_MA_METHOD stochMaMethod = MODE_SMA; // Ma Method +input ENUM_STO_PRICE stochMode = STO_LOWHIGH; // Calculation Mode + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 0 + +// +// ATR ... +#define atrBufferIndex 0 +double atrBuffer[]; + +// +// RVI ... +#define rviMainBufferIndex 1 +#define rviSignalBufferIndex 2 +double rviMainBuffer[]; +double rviSignalBuffer[]; + +// +// BULLPOWER ... +#define bullPBufferIndex 3 +double bullPBuffer[]; + +// +// BEARPOWER ... +#define bearPBufferIndex 4 +double bearPBuffer[]; + +// +// VOLUME ... +#define volumeBufferIndex 5 +double volumeBuffer[]; + +// +// RSI ... +#define rsiBufferIndex 6 +double rsiBuffer[]; + +// +// CCI ... +#define cciBufferIndex 7 +double cciBuffer[]; + +// +// MOMENTUM ... +#define momentumBufferIndex 8 +double momentumBuffer[]; + +// +// SAR ... +#define sarBufferIndex 9 +double sarBuffer[]; + +// +// MACD ... +#define macdMainBufferIndex 10 +#define macdSignalBufferIndex 11 +double macdMainBuffer[]; +double macdSignalBuffer[]; + +// +// STOCHASTIC ... +#define stochMainBufferIndex 12 +#define stochSignalBufferIndex 13 +double stochMainBuffer[]; +double stochSignalBuffer[]; + +// +// STANDARDDEVIATION ... +#define stddevBufferIndex 14 +double stddevBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; +int rviHandler = INVALID_HANDLE; +int bullPHandler = INVALID_HANDLE; +int bearPHandler = INVALID_HANDLE; +int volumeHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int cciHandler = INVALID_HANDLE; +int momentumHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int macdHandler = INVALID_HANDLE; +int stochHandler = INVALID_HANDLE; +int stddevHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing Handlers ... + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + + // + // RVI ... + rviHandler = iRVI( + _Symbol, + _Period, + rviLength); + + // + // BULLSPOWER ... + bullPHandler = iBullsPower( + _Symbol, + _Period, + bullpLength); + + // + // BEARSPOWER ... + bearPHandler = iBearsPower( + _Symbol, + _Period, + bullpLength); + + // + // VOLUMES ... + volumeHandler = iVolumes( + _Symbol, + _Period, + volumeAppliedTo); + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + rsiLength, + rsiAppliedTo); + + // + // CCI ... + cciHandler = iCCI( + _Symbol, + _Period, + cciLength, + cciAppliedTo); + + // + // MOMENTUM ... + momentumHandler = iMomentum( + _Symbol, + _Period, + momentumLength, + momentumAppliedTo); + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMaximum); + + // + // MACD ... + macdHandler = iMACD( + _Symbol, + _Period, + macdFastLength, + macdSlowLength, + macdSignaLength, + macdAppliedTo); + + // + // STOCHASTIC ... + stochHandler = iStochastic( + _Symbol, + _Period, + stochKLength, + stochDLength, + stochSlowing, + stochMaMethod, + stochMode); + + // + // STANDARDDEVIATION ... + stddevHandler = iStdDev( + _Symbol, + _Period, + stddevLength, + stddevShift, + stddevMethod, + stddevAppliedTo); + + // + bool isAllHandlersInit = + // + atrHandler != INVALID_HANDLE && + rviHandler != INVALID_HANDLE && + bullPHandler != INVALID_HANDLE && + bearPHandler != INVALID_HANDLE && + volumeHandler != INVALID_HANDLE && + rsiHandler != INVALID_HANDLE && + cciHandler != INVALID_HANDLE && + momentumHandler != INVALID_HANDLE && + sarHandler != INVALID_HANDLE && + macdHandler != INVALID_HANDLE && + stochHandler != INVALID_HANDLE && + stddevHandler != INVALID_HANDLE + // + ; + if (!isAllHandlersInit) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); + IndicatorRelease(rviHandler); + IndicatorRelease(bullPHandler); + IndicatorRelease(bearPHandler); + IndicatorRelease(volumeHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(cciHandler); + IndicatorRelease(momentumHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(macdHandler); + IndicatorRelease(stochHandler); + IndicatorRelease(stddevHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int atrCalculatedBars = BarsCalculated(atrHandler); + int rviCalculatedBars = BarsCalculated(rviHandler); + int bullPCalculatedBars = BarsCalculated(bullPHandler); + int bearPCalculatedBars = BarsCalculated(bearPHandler); + int volumeCalculatedBars = BarsCalculated(volumeHandler); + int rsiCalculatedBars = BarsCalculated(rsiHandler); + int cciCalculatedBars = BarsCalculated(cciHandler); + int momentumCalculatedBars = BarsCalculated(momentumHandler); + int sarCalculatedBars = BarsCalculated(sarHandler); + int macdCalculatedBars = BarsCalculated(macdHandler); + int stochCalculatedBars = BarsCalculated(stochHandler); + int stddevCalculatedBars = BarsCalculated(stddevHandler); + + // + bool isCalculatedBarsPassed = + // + atrCalculatedBars >= maxLength && + rviCalculatedBars >= maxLength && + bullPCalculatedBars >= maxLength && + bearPCalculatedBars >= maxLength && + volumeCalculatedBars >= maxLength && + rsiCalculatedBars >= maxLength && + cciCalculatedBars >= maxLength && + momentumCalculatedBars >= maxLength && + sarCalculatedBars >= maxLength && + macdCalculatedBars >= maxLength && + stochCalculatedBars >= maxLength && + stddevCalculatedBars >= maxLength + // + ; + if (!isCalculatedBarsPassed) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int atrCopiedItems = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer); + int rviMainCopiedItems = CopyBuffer(rviHandler, MAIN_LINE, 0, limit, rviMainBuffer); + int rviSignalCopiedItems = CopyBuffer(rviHandler, SIGNAL_LINE, 0, limit, rviSignalBuffer); + int bullPCopiedItems = CopyBuffer(bullPHandler, 0, 0, limit, bullPBuffer); + int bearPCopiedItems = CopyBuffer(bearPHandler, 0, 0, limit, bearPBuffer); + int volumeCopiedItems = CopyBuffer(volumeHandler, 0, 0, limit, volumeBuffer); + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + int cciCopiedItems = CopyBuffer(cciHandler, 0, 0, limit, cciBuffer); + int momentumCopiedItems = CopyBuffer(momentumHandler, 0, 0, limit, momentumBuffer); + int sarCopiedItems = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); + int macdMainCopiedItems = CopyBuffer(macdHandler, MAIN_LINE, 0, limit, macdMainBuffer); + int macdSignalCopiedItems = CopyBuffer(macdHandler, SIGNAL_LINE, 0, limit, macdSignalBuffer); + int stochMainCopiedItems = CopyBuffer(stochHandler, MAIN_LINE, 0, limit, stochMainBuffer); + int stocSignalhCopiedItems = CopyBuffer(stochHandler, SIGNAL_LINE, 0, limit, stochSignalBuffer); + int stddevCopiedItems = CopyBuffer(stddevHandler, 0, 0, limit, stddevBuffer); + + // + bool isCopiedBarsPassed = + // + atrCopiedItems > 0 && + rviMainCopiedItems > 0 && + rviSignalCopiedItems > 0 && + bullPCopiedItems > 0 && + bearPCopiedItems > 0 && + volumeCopiedItems > 0 && + rsiCopiedItems > 0 && + cciCopiedItems > 0 && + momentumCopiedItems > 0 && + sarCopiedItems > 0 && + macdMainCopiedItems > 0 && + macdSignalCopiedItems > 0 && + stochMainCopiedItems > 0 && + stocSignalhCopiedItems > 0 && + stddevCopiedItems > 0 + // + ; + if (!isCopiedBarsPassed) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + // HERE We Do Not anything ... + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 && + rviLength >= 2 && + bullpLength >= 2 && + bearpLength >= 2 && + rsiLength >= 2 && + cciLength >= 2 && + momentumLength >= 2 && + sarStep > 0 && + sarStep < sarMaximum && + macdFastLength >= 2 && + macdSlowLength > macdFastLength && + macdSignaLength >= 2 && + stochKLength >= 2 && + stochDLength >= 2 && + stochSlowing >= 2 && + stddevLength >= 2 && + stddevShift >= 0 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(atrLength, rviLength); + result = MathMax(result, bullpLength); + result = MathMax(result, bearpLength); + result = MathMax(result, rsiLength); + result = MathMax(result, cciLength); + result = MathMax(result, momentumLength); + result = MathMax(result, macdFastLength); + result = MathMax(result, macdSlowLength); + result = MathMax(result, macdSignaLength); + result = MathMax(result, stochKLength); + result = MathMax(result, stochDLength); + result = MathMax(result, stochSlowing); + result = MathMax(result, stddevLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // DATA Buffers ... + + // + // ATR ... + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // RVI ... + + // + // Main ... + ArraySetAsSeries(rviMainBuffer, true); + SetIndexBuffer(rviMainBufferIndex, rviMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(rviSignalBuffer, true); + SetIndexBuffer(rviSignalBufferIndex, rviSignalBuffer, INDICATOR_CALCULATIONS); + + // + // BULLPOWER ... + ArraySetAsSeries(bullPBuffer, true); + SetIndexBuffer(bullPBufferIndex, bullPBuffer, INDICATOR_CALCULATIONS); + + // + // BEARPOWER ... + ArraySetAsSeries(bearPBuffer, true); + SetIndexBuffer(bearPBufferIndex, bearPBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + ArraySetAsSeries(volumeBuffer, true); + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS); + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // CCI ... + ArraySetAsSeries(cciBuffer, true); + SetIndexBuffer(cciBufferIndex, cciBuffer, INDICATOR_CALCULATIONS); + + // + // MOMENTUM ... + ArraySetAsSeries(momentumBuffer, true); + SetIndexBuffer(momentumBufferIndex, momentumBuffer, INDICATOR_CALCULATIONS); + + // + // SAR ... + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_CALCULATIONS); + + // + // STANDARDDEVIATION ... + ArraySetAsSeries(stddevBuffer, true); + SetIndexBuffer(stddevBufferIndex, stddevBuffer, INDICATOR_CALCULATIONS); + + // + // MACD ... + + // + // Main ... + ArraySetAsSeries(macdMainBuffer, true); + SetIndexBuffer(macdMainBufferIndex, macdMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(macdSignalBuffer, true); + SetIndexBuffer(macdSignalBufferIndex, macdSignalBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xpv.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xpv.mq5 new file mode 100644 index 0000000..d724dd2 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xpv.mq5 @@ -0,0 +1,1211 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XPV +// Description: Peaks and Vales ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XPV Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "XPV" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Makret Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +input group "Fibonacci"; +input double fiboLevel1 = 0.236; // Fibio 1st Level +input double fiboLevel2 = 0.382; // Fibio 2st Level +input double fiboLevel3 = 0.5; // Fibio 3rd Level +input double fiboLevel4 = 0.618; // Fibio 4th Level +input double fiboLevel5 = 0.764; // Fibio 5th Level + +// +input group "Boundary Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showLevels = false; // Show Levels +input bool showConsolidations = false; // Show Consolidations +input bool showFibo1Levels = false; // Show Fibo 1st Level +input bool showFibo2Levels = false; // Show Fibo 2nd Level +input bool showFibo3Levels = false; // Show Fibo 3rd Level +input bool showFibo4Levels = false; // Show Fibo 4th Level +input bool showFibo5Levels = false; // Show Fibo 5th Level + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 32 +#property indicator_plots 32 + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "XPV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "XPV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "XPV R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "XPV S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "XPV FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "XPV FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "XPV FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// FIBBO Level 4 ... + +// +#define fl4BufferIndex 12 +#define fl4BufferPlotIndex 7 +double fl4Buffer[]; + +// +#define fl4ColorBufferIndex 13 +double fl4ColorBuffer[]; + +// +#property indicator_label8 "XPV FL4" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrGold +#property indicator_style8 STYLE_DASHDOTDOT +#property indicator_width8 1 + +// +// FIBBO Level 5 ... + +// +#define fl5BufferIndex 14 +#define fl5BufferPlotIndex 8 +double fl5Buffer[]; + +// +#define fl5ColorBufferIndex 15 +double fl5ColorBuffer[]; + +// +#property indicator_label9 "XPV FL5" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrGold +#property indicator_style9 STYLE_DASHDOTDOT +#property indicator_width9 1 + +// +// LEVELS ... + +// +#define scHHBufferIndex 16 +#define scHHBufferPlotIndex 9 +double scHHBuffer[]; + +// +#define scHHColorBufferIndex 17 +double scHHColorBuffer[]; + +// +#property indicator_label10 "XPV SHH" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +#define scLLBufferIndex 18 +#define scLLBufferPlotIndex 10 +double scLLBuffer[]; + +// +#define scLLColorBufferIndex 19 +double scLLColorBuffer[]; + +// +#property indicator_label11 "XPV SLL" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define mcHHBufferIndex 20 +#define mcHHBufferPlotIndex 11 +double mcHHBuffer[]; + +// +#define mcHHColorBufferIndex 21 +double mcHHColorBuffer[]; + +// +#property indicator_label12 "XPV MHH" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define mcLLBufferIndex 22 +#define mcLLBufferPlotIndex 12 +double mcLLBuffer[]; + +// +#define mcLLColorBufferIndex 23 +double mcLLColorBuffer[]; + +// +#property indicator_label13 "XPV MLL" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define lcHHBufferIndex 24 +#define lcHHBufferPlotIndex 13 +double lcHHBuffer[]; + +// +#define lcHHColorBufferIndex 25 +double lcHHColorBuffer[]; + +// +#property indicator_label14 "XPV LHH" +#property indicator_type14 DRAW_COLOR_LINE +#property indicator_color14 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define lcLLBufferIndex 26 +#define lcLLBufferPlotIndex 14 +double lcLLBuffer[]; + +// +#define lcLLColorBufferIndex 27 +double lcLLColorBuffer[]; + +// +#property indicator_label15 "XPV LLL" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define hcHHBufferIndex 28 +#define hcHHBufferPlotIndex 15 +double hcHHBuffer[]; + +// +#define hcHHColorBufferIndex 29 +double hcHHColorBuffer[]; + +// +#property indicator_label16 "XPV HHH" +#property indicator_type16 DRAW_COLOR_LINE +#property indicator_color16 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +#define hcLLBufferIndex 30 +#define hcLLBufferPlotIndex 16 +double hcLLBuffer[]; + +// +#define hcLLColorBufferIndex 31 +double hcLLColorBuffer[]; + +// +#property indicator_label17 "XPV HLL" +#property indicator_type17 DRAW_COLOR_LINE +#property indicator_color17 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +double mHideColorIDX = 0; + +// +XMarketCycle sc; +double mLastSCHH = 0; +double mLastSCLL = 0; + +// +XMarketCycle mc; +double mLastMCHH = 0; +double mLastMCLL = 0; + +// +XMarketCycle lc; +double mLastLCHH = 0; +double mLastLCLL = 0; + +// +XMarketCycle hc; +double mLastHCHH = 0; +double mLastHCLL = 0; + +// +double lastPeak = 0; +double lastVale = 0; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... + // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(sc.length, mc.length); + result = MathMax(result, lc.length); + result = MathMax(result, hc.length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // Buffer ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // Buffer ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // Buffer ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 4 ... + + // + // Buffer ... + ArraySetAsSeries(fl4Buffer, true); + SetIndexBuffer(fl4BufferIndex, fl4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_SHOW_DATA, showFibo4Levels); + + // + // Color ... + ArraySetAsSeries(fl4ColorBuffer, true); + SetIndexBuffer(fl4ColorBufferIndex, fl4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 5 ... + + // + // Buffer ... + ArraySetAsSeries(fl5Buffer, true); + SetIndexBuffer(fl5BufferIndex, fl5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_SHOW_DATA, showFibo5Levels); + + // + // Color ... + ArraySetAsSeries(fl5ColorBuffer, true); + SetIndexBuffer(fl5ColorBufferIndex, fl5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scHHColorBuffer, true); + SetIndexBuffer(scHHColorBufferIndex, scHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scLLColorBuffer, true); + SetIndexBuffer(scLLColorBufferIndex, scLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcHHColorBuffer, true); + SetIndexBuffer(mcHHColorBufferIndex, mcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcLLColorBuffer, true); + SetIndexBuffer(mcLLColorBufferIndex, mcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcHHColorBuffer, true); + SetIndexBuffer(lcHHColorBufferIndex, lcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcLLColorBuffer, true); + SetIndexBuffer(lcLLColorBufferIndex, lcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hcHHBuffer, true); + SetIndexBuffer(hcHHBufferIndex, hcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcHHColorBuffer, true); + SetIndexBuffer(hcHHColorBufferIndex, hcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(hcLLBuffer, true); + SetIndexBuffer(hcLLBufferIndex, hcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcLLColorBuffer, true); + SetIndexBuffer(hcLLColorBufferIndex, hcLLColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Cycles ... + CalculateCycles(bar_index); + + // + // Calculate Peaks and Vales ... + CalculatePeaksAndVales(bar_index); + + // + // Calculate Fibonnaci ... + CalculateFibonacci(bar_index); +} + +// +// Custom ... + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Short ... + result = sc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_SHORT, + scMethod, + scPeriod + // + ); + if (!result) + { + return result; + } + + // + // Medium ... + result = mc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_MEDIUM, + mcMethod, + mcPeriod + // + ); + if (!result) + { + return result; + } + + // + // Long ... + result = lc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_LONG, + lcMethod, + lcPeriod + // + ); + if (!result) + { + return result; + } + + // + // Hind ... + result = hc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_HIND, + hcMethod, + hcPeriod + // + ); + + // + return result; +} + +// +// Calculate Specified Cycles HH and LL ... +void CalculateCycle( + int barIndex, + XMarketCycle &cycle, + double &lastHH, + double &hhBuffer[], + double &hhColorBuffer[], + double &lastLL, + double &llBuffer[], + double &llColorBuffer[] // +) +{ + // + cycle.Update(barIndex); + + // + XOHCL bar; + bar.Init( + _Symbol, + _Period, + barIndex + // + ); + + // + double hhValue = bar.FindHighest( + cycle.length, + hhMode + // + ); + hhBuffer[barIndex] = hhValue; + + // + double hhColorIDX = + !showLevels + ? mHideColorIDX + : (hhValue == lastHH) + ? !showConsolidations + ? mHideColorIDX + : 1 + : hhValue > lastHH + ? 2 + : hhValue < lastHH + ? 3 + : mHideColorIDX; + hhColorBuffer[barIndex] = hhColorIDX; + + // + lastHH = hhValue; + + // + double llValue = bar.FindLowest( + cycle.length, + llMode + // + ); + llBuffer[barIndex] = llValue; + + // + double llColorIDX = + !showLevels + ? mHideColorIDX + : (llValue == lastLL) + ? !showConsolidations + ? mHideColorIDX + : 1 + : llValue > lastLL + ? 2 + : llValue < lastLL + ? 3 + : mHideColorIDX; + llColorBuffer[barIndex] = llColorIDX; + + // + lastLL = llValue; +} + +// +// Calculate Cycles Up and Down Boundaries ... +void CalculateCycles( + int barIndex // Bar Index +) +{ + // + // Short ... + CalculateCycle( + barIndex, + sc, + // + mLastSCHH, + scHHBuffer, + scHHColorBuffer, + // + mLastSCLL, + scLLBuffer, + scLLColorBuffer + // + ); + + // + // Medium ... + CalculateCycle( + barIndex, + mc, + // + mLastMCHH, + mcHHBuffer, + mcHHColorBuffer, + // + mLastMCLL, + mcLLBuffer, + mcLLColorBuffer + // + ); + + // + // Long ... + CalculateCycle( + barIndex, + lc, + // + mLastLCHH, + lcHHBuffer, + lcHHColorBuffer, + // + mLastLCLL, + lcLLBuffer, + lcLLColorBuffer + // + ); + + // + // Hind ... + CalculateCycle( + barIndex, + hc, + // + mLastHCHH, + hcHHBuffer, + hcHHColorBuffer, + // + mLastHCLL, + hcLLBuffer, + hcLLColorBuffer + // + ); +} + +// +// Calculate Peaks and Values ... +void CalculatePeaksAndVales( + int barIndex // Bar Index +) +{ + // + // Retrieve Requirements ... + + // + // Short ... + double scHHValue = scHHBuffer[barIndex]; + double scLLValue = scLLBuffer[barIndex]; + + // + // Medium ... + double mcHHValue = mcHHBuffer[barIndex]; + double mcLLValue = mcLLBuffer[barIndex]; + + // + // Long ... + double lcHHValue = lcHHBuffer[barIndex]; + double lcLLValue = lcLLBuffer[barIndex]; + + // + // Hind ... + double hcHHValue = hcHHBuffer[barIndex]; + double hcLLValue = hcLLBuffer[barIndex]; + + // + double rColorIDX = mHideColorIDX; + double sColorIDX = mHideColorIDX; + + // + // RESISTANCE ... + double rValue = (scHHValue + mcHHValue + lcHHValue + hcHHValue) / 4; + + // + // PEAKS ... + bool isPeak = rValue == hcHHValue && + hcHHValue == lcHHValue && + lcHHValue == mcHHValue && + mcHHValue == scHHValue; + + // + if (isPeak && lastPeak != rValue) + { + // + rColorIDX = 1; + lastPeak = rValue; + } + + // + // SUPPORT ... + double sValue = (scLLValue + mcLLValue + lcLLValue + hcLLValue) / 4; + + // + // VALES ... + bool isVale = sValue == hcLLValue && + hcLLValue == lcLLValue && + lcLLValue == mcLLValue && + mcLLValue == scLLValue; + + // + if (isVale && lastVale != sValue) + { + // + sColorIDX = 1; + + // + lastVale = sValue; + } + + // + rBuffer[barIndex] = rValue; + sBuffer[barIndex] = sValue; + peaksBuffer[barIndex] = lastPeak; + valesBuffer[barIndex] = lastVale; + + // + if (showPeaksAndVales) + { + // + rColorBuffer[barIndex] = rColorIDX; + sColorBuffer[barIndex] = sColorIDX; + } + else + { + // + rColorBuffer[barIndex] = mHideColorIDX; + sColorBuffer[barIndex] = mHideColorIDX; + } +} + +// +// Calculate Fibonacci Level 1 ... +void CalculateFibonacci( + int barIndex // Bar Index +) +{ + // + // Select Requirements ... + double upPrice = peaksBuffer[barIndex]; + double downPrice = valesBuffer[barIndex]; + + // + // Level 1 ... + double fibLevel1Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + // + // Level 2 ... + double fibLevel2Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + + // + // Level 3 ... + double fibLevel3Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + + // + // Level 4 ... + double fibLevel4Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel4, + 1); + + // + // Level 5 ... + double fibLevel5Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel5, + 1); + + // + fl1Buffer[barIndex] = fibLevel1Value; + fl2Buffer[barIndex] = fibLevel2Value; + fl3Buffer[barIndex] = fibLevel3Value; + fl4Buffer[barIndex] = fibLevel4Value; + fl5Buffer[barIndex] = fibLevel5Value; + + // + double fl1ColorIdx = showFibo1Levels ? 1 : mHideColorIDX; + double fl2ColorIdx = showFibo2Levels ? 1 : mHideColorIDX; + double fl3ColorIdx = showFibo3Levels ? 1 : mHideColorIDX; + double fl4ColorIdx = showFibo4Levels ? 1 : mHideColorIDX; + double fl5ColorIdx = showFibo5Levels ? 1 : mHideColorIDX; + + // + fl1ColorBuffer[barIndex] = fl1ColorIdx; + fl2ColorBuffer[barIndex] = fl2ColorIdx; + fl3ColorBuffer[barIndex] = fl3ColorIdx; + fl4ColorBuffer[barIndex] = fl4ColorIdx; + fl5ColorBuffer[barIndex] = fl5ColorIdx; +} + +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xrsi.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xrsi.mq5 new file mode 100644 index 0000000..f581113 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xrsi.mq5 @@ -0,0 +1,394 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Oscillator +// ------------------------------------------------------ +// Name: XRSI +// Description: detect market conditions based on RSI ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XRSI Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XRSI" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 14; // Market Length +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +input group "Short Entry"; +input double shortEntryValue = 70; // Short Entry Level +input color shortEntryColor = clrRed; // Short Entry Level Color +input ENUM_LINE_STYLE shortEntryLineStyle = STYLE_DOT; // Short Entry Style + +// +input group "Short Exit"; +input double shortExitValue = 40; // Short Exit Level +input color shortExitColor = clrRed; // Short Exit Level Color +input ENUM_LINE_STYLE shortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +input group "Long Entry"; +input double longEntryValue = 30; // Long Entry Level +input color longEntryColor = clrRed; // Long Entry Level Color +input ENUM_LINE_STYLE longEntryLineStyle = STYLE_DOT; // Long Entry Style + +// +input group "Long Exit"; +input double longExitValue = 60; // Long Exit Level +input color longExitColor = clrRed; // Long Exit Level Color +input ENUM_LINE_STYLE longExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// START Inputs ... +// + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +// #property indicator_separate_window +#property indicator_chart_window +#property indicator_buffers 2 +// #property indicator_plots 1 +#property indicator_plots 0 + +// +#define rsiBufferIndex 0 +#define rsiColorBufferIndex 1 + +// +double rsiBuffer[]; +double rsiColorBuffer[]; + +// +// #property indicator_label1 "XRSI" +// #property indicator_type1 DRAW_COLOR_LINE +// #property indicator_color1 clrAqua, clrGray, clrFuchsia +// #property indicator_style1 STYLE_DOT +// #property indicator_width1 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int rsiHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + rsiHandler = iRSI( + _Symbol, + _Period, + length, + appliedTo); + if (rsiHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(rsiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + int rsiCalculatedBars = BarsCalculated(rsiHandler); + if (rsiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + if (rsiCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RSI ... + string rsiBufferLabel = ShortName + " (" + (string)length + ")"; + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(rsiBufferIndex, PLOT_DRAW_BEGIN, length); + // PlotIndexSetString(rsiBufferIndex, PLOT_LABEL, rsiBufferLabel); + + // // + // // RSI Color Buffer ... + ArraySetAsSeries(rsiColorBuffer, true); + SetIndexBuffer(rsiColorBufferIndex, rsiColorBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(rsiColorBufferIndex, rsiColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set Indicator Levels here ... + // OB, ExitLong, ExitShort, OS ... + IndicatorSetInteger(INDICATOR_LEVELS, 4); + + // + // SHORTENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, shortEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, shortEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, shortEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 0, "Short Entry"); + + // + // LONGEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, longExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, longExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, shortExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Long Exit"); + + // + // SHORTEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 2, shortExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 2, shortExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 2, longEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 2, "Short Exit"); + + // + // LONGENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 3, longEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 3, longEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 3, longExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 3, "Long Entry"); + + // + // Set Maximum and Minimum for subwindow + IndicatorSetInteger(INDICATOR_DIGITS, 2); + IndicatorSetDouble(INDICATOR_MINIMUM, 0); + IndicatorSetDouble(INDICATOR_MAXIMUM, 100); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + double iValue = rsiBuffer[bar_index]; + + // + double iColorIndex = 0; + + // + if ( + iValue >= shortEntryValue || + iValue <= longEntryValue || + (iValue < longExitValue && + iValue > shortExitValue)) + { + iColorIndex = 0; + } + else if ( + iValue <= shortEntryValue && + iValue >= longExitValue) + { + iColorIndex = 2; + } + else if ( + iValue < shortExitValue && + iValue > longEntryValue) + { + iColorIndex = 1; + } + + // + rsiColorBuffer[bar_index] = iColorIndex; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xsslc.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xsslc.mq5 new file mode 100644 index 0000000..620cb24 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xsslc.mq5 @@ -0,0 +1,440 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ---------------------------------------------------- +// Name: XSSLC +// Description: SSL Channel Indicator +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XSSLC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XSSLC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 36; // Length + +// +input group "Calculation"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Applied To +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Applied To + +// +input group "Presentation"; +input bool showUp = true; // Show Up +input bool showDown = true; // Show Down + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 2 + +// +// PLOTTED Buffers ... + +// +#define upBufferIndex 0 +double upBuffer[]; + +// +#property indicator_label1 "XSSLC Up" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#define downBufferIndex 1 +double downBuffer[]; + +// +#property indicator_label2 "XSSLC Down" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +#define upMaBufferIndex 2 +double upMaBuffer[]; + +// +#define downMaBufferIndex 3 +double downMaBuffer[]; + +// +#define kpiBufferIndex 4 +double kpiBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int upHandler = INVALID_HANDLE; +int downHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize Requierd Handlers ... + upHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + upAppliedTo); + downHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + downAppliedTo); + if (upHandler == INVALID_HANDLE || downHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + Print(msg); + + // + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Release Indicators ... + IndicatorRelease(upHandler); + IndicatorRelease(downHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int upCalculatedBars = BarsCalculated(upHandler); + int downCalculatedBars = BarsCalculated(downHandler); + if (upCalculatedBars < maxLength || + downCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedUps = CopyBuffer(upHandler, 0, 0, limit, upMaBuffer); + int copiedDowns = CopyBuffer(downHandler, 0, 0, limit, downMaBuffer); + if (copiedUps <= 0 || + copiedDowns <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, limit, rates_total, prev_calculated, close); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (length > 2) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP ... + + // + ENUM_DRAW_TYPE upDrawType = showUp ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(upBuffer, true); + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upBufferIndex, PLOT_SHOW_DATA, showUp); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_TYPE, upDrawType); + + // + // DOWN ... + + // + ENUM_DRAW_TYPE downDrawType = showDown ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(downBuffer, true); + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downBufferIndex, PLOT_SHOW_DATA, showDown); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_TYPE, downDrawType); + + // + // DATA Buffers ... + + // + // UP MA ... + ArraySetAsSeries(upMaBuffer, true); + SetIndexBuffer(upMaBufferIndex, upMaBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN MA ... + ArraySetAsSeries(downMaBuffer, true); + SetIndexBuffer(downMaBufferIndex, downMaBuffer, INDICATOR_CALCULATIONS); + + // + // KPI ... + ArraySetAsSeries(kpiBuffer, true); + SetIndexBuffer(kpiBufferIndex, kpiBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = upMaBuffer[bar_index]; + double downMaValue = downMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) + { + kpiValue = 1; + } + else if (closeValue < downMaValue) + { + kpiValue = -1; + } + else + { + kpiValue = kpiBuffer[bar_index + 1]; + } + + // + kpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + upBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + downBuffer[bar_index] = downValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xstr.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xstr.mq5 new file mode 100644 index 0000000..90e6eeb --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xstr.mq5 @@ -0,0 +1,580 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XSTR +// Description: Super Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XSTR" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Market ... +input group "ATR"; +input int atrLength = 14; // Length +input double atrMultiplier = 3.0; // Multiplier +input ENUM_APPLIED_PRICE atrAppliedTo = PRICE_MEDIAN; // Applied To + +// +// Presentation ... +input group "Presentation"; +input bool showTrends = true; // Show Trends +input bool fillTrends = true; // Fill Trends + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 2 + +// +#define fillUpBufferIndex 0 +double fillUpBuffer[]; + +#define fillDownBufferIndex 1 +double fillDownBuffer[]; + +// +#define fillingPlotBufferIndex 0 + +// +#property indicator_label1 "XSTR Filling" +#property indicator_type1 DRAW_FILLING +#property indicator_color1 clrBisque, clrPaleGreen + +// +#define mainBufferIndex 2 +#define mainPlotBufferIndex 1 +double mainBuffer[]; + +// +#define mainColorBufferIndex 3 +double mainColorBuffer[]; + +// +#property indicator_label2 "XSTR" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style2 STYLE_DOT + +// +// DATA Buffers ... + +// +#define atrBufferIndex 4 +double atrBuffer[]; + +// +#define trendBufferIndex 5 +double trendBuffer[]; + +// +#define upBufferIndex 6 +double upBuffer[]; + +// +#define downBufferIndex 7 +double downBuffer[]; + +// +#define priceBufferIndex 8 +double priceBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + if (atrHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return 0; + } + + // + // Check Number of items Copy or not ... + int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer); + if (copiedATRs <= 0) + { + return 0; + } + + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + // Calculated Price ... + double price = getPrice( + atrAppliedTo, + open, + high, + low, + close, + i); + // price = (high[i] + low[i]) / 2; + priceBuffer[i] = price; + + // + double atr = atrBuffer[i]; + + // + // Up ... + upBuffer[i] = price + (atrMultiplier * atr); + + // + // Down ... + downBuffer[i] = price - (atrMultiplier * atr); + + // + if (close[i] > upBuffer[i - 1]) + { + // + trendBuffer[i] = 1; + if (trendBuffer[i - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[i] < downBuffer[i - 1]) + { + // + trendBuffer[i] = -1; + if (trendBuffer[i - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trendBuffer[i - 1] == 1) + { + // + trendBuffer[i] = 1; + changeOfTrend = 0; + } + else if (trendBuffer[i - 1] == -1) + { + // + trendBuffer[i] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trendBuffer[i] < 0 && trendBuffer[i - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trendBuffer[i] > 0 && trendBuffer[i - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trendBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1]) + { + downBuffer[i] = downBuffer[i - 1]; + } + + // + if (trendBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1]) + { + upBuffer[i] = upBuffer[i - 1]; + } + + // + if (startBearishTrend == 1) + { + upBuffer[i] = priceBuffer[i] + (atrMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + downBuffer[i] = priceBuffer[i] - (atrMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = 0; + mainColorBuffer[i] = colorIDX; + + // + if (trendBuffer[i] == 1) + { + // + mainBuffer[i] = downBuffer[i]; + if (changeOfTrend == 1) + { + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 1; + } + else if (trendBuffer[i] == -1) + { + // + mainBuffer[i] = upBuffer[i]; + if (changeOfTrend == 1) + { + // + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 2; + } + + // + if (showTrends) + { + mainColorBuffer[i] = colorIDX; + } + + // + // Filling ... + if (fillTrends) + { + // + fillUpBuffer[i] = mainBuffer[i]; + fillDownBuffer[i] = close[i]; + } + else + { + // + fillUpBuffer[i] = EMPTY_VALUE; + fillDownBuffer[i] = EMPTY_VALUE; + } + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = atrLength; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PLOT Buffers ... + + // + // FILLINGS ... + SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA); + SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fillingPlotBufferIndex, PLOT_SHOW_DATA, false); + + // + // MAIN ... + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mainPlotBufferIndex, PLOT_SHOW_DATA, showTrends); + SetIndexBuffer(mainColorBufferIndex, mainColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA Buffers ... + + // + // ATR ... + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // TREND ... + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_CALCULATIONS); + + // + // UP ... + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN ... + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + + // + // PRICE ... + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.mq5 new file mode 100644 index 0000000..ca79695 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.mq5 @@ -0,0 +1,457 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Trend Detector Oscillator +// -------------------------------------------------- +// Name: XTD +// Description: trend detecting in both sides ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTD Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTD" + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 14; // Market Length +input bool drawCrosses = true; // Draw Cross Arrows + +// +// Bullish ... +input uchar bullishArrowCode = 228; // Cross Over Arrow Code +input color bullishArrowColor = clrAqua; // Cross Over Arrow Color + +// +// Bearish ... +input uchar bearishArrowCode = 230; // Cross Under Arrow Code +input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +// #property indicator_separate_window +#property indicator_chart_window + +// +#property indicator_buffers 3 +// #property indicator_plots 3 +#property indicator_plots 0 + +// +#define bullishBufferIndex 0 +#define bearishBufferIndex 1 +#define signalBufferIndex 2 + +// +double bullishBuffer[]; +double bearishBuffer[]; +double signalBuffer[]; + +// +// #property indicator_label1 "XBullPower" +// #property indicator_type1 DRAW_LINE +// #property indicator_color1 clrLime +// #property indicator_style1 STYLE_SOLID +// #property indicator_width1 1 + +// +// #property indicator_label2 "XBearPower" +// #property indicator_type2 DRAW_LINE +// #property indicator_color2 clrRed +// #property indicator_style2 STYLE_SOLID +// #property indicator_width2 1 + +// +// #property indicator_label3 "XSignal" +// #property indicator_type3 DRAW_LINE +// #property indicator_color3 clrGold +// #property indicator_style3 STYLE_DOT +// #property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +int xtdBullishCandleCount = 0; +int xtdBearishCandleCount = 0; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i, close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 5) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Bullish Buffer ... + string bullishBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishBuffer, true); + SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length); + // PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel); + + // + // Bearish Buffer ... + string bearishBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishBuffer, true); + SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length); + // PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + "Signal " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + // PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, + const double &close[]) +{ + // + // Reset Global Counters ... + xtdBullishCandleCount = 0; + xtdBearishCandleCount = 0; + + // + // Loop through Closes ... + for (int i = bar_index; i <= bar_index + length; i++) + { + for (int j = i + 1; j <= bar_index + length; j++) + { + // + if (close[i] > close[j]) + { + xtdBullishCandleCount++; + } + + // + if (close[i] < close[j]) + { + xtdBearishCandleCount++; + } + } + } + + // + // Bullish Power Buffer ... + bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount); + + // + // Bearish Power Buffer ... + bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount); + + // + // Signal Buffer ... + signalBuffer[bar_index] = bullishBuffer[bar_index] - bearishBuffer[bar_index]; + + // + // Check and Draw Crosses if it's Specified ... + if (drawCrosses) + { + DrawCrosses(bar_index); + } +} + +// +// +double GetState( + int bar_index // Specified Bar Index +) +{ + // + // Check Cross Points ... + // bullishCrossedOverBearish = 2; + // bullishOverBearish = 1; + // bullishCrossedUnderBearish = -2; + // bullishUnderBearish = -1; + // OtherWise = 0; + bool isBullishCrossedOverBearish = IsCrossedOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishCrossedUnderBearish = IsCrossedUnder( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishOverBearish = IsOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishUnderBearish = IsUnder( + bullishBuffer, + bearishBuffer, + bar_index); + + // + double result = X_XTD_NEUTURAL; + if (isBullishCrossedOverBearish) + { + result = X_XTD_BULLISH_CROSSED_OVER_BEARISH; + } + else if (isBullishCrossedUnderBearish) + { + result = X_XTD_BULLISH_CROSSED_UNDER_BEARISH; + } + else if (isBullishOverBearish) + { + result = X_XTD_BULLISH_OVER_BEARISH; + } + else if (isBullishUnderBearish) + { + result = X_XTD_BULLISH_UNDER_BEARISH; + } + else + { + result = X_XTD_NEUTURAL; + } + + // + return result; +} + +// +// Draw Crosses ... +void DrawCrosses( + int bar_index // the bars which required to draw cross arrow on it ... +) +{ + // + double stateValue = GetState(bar_index); + + // + bool isOver = stateValue == 2; + double low = iLow(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + + // + double price = isOver ? low : high; + datetime time = iTime(_Symbol, _Period, bar_index); + ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM; + uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode; + color arrowColor = isOver ? bullishArrowColor : bearishArrowColor; + string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price; + + // + DrawArrow( + 0, + crossName, + 0, + time, + price, + arrowCode, + anchor, + arrowColor); +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.osc.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.osc.mq5 new file mode 100644 index 0000000..4f40f3c --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtd.osc.mq5 @@ -0,0 +1,457 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Trend Detector Oscillator +// -------------------------------------------------- +// Name: XTD +// Description: trend detecting in both sides ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTD Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTD" + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 14; // Market Length +input bool drawCrosses = true; // Draw Cross Arrows + +// +// Bullish ... +input uchar bullishArrowCode = 228; // Cross Over Arrow Code +input color bullishArrowColor = clrAqua; // Cross Over Arrow Color + +// +// Bearish ... +input uchar bearishArrowCode = 230; // Cross Under Arrow Code +input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window +// #property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 2 +// #property indicator_plots 0 + +// +#define bullishBufferIndex 0 +#define bearishBufferIndex 1 +#define signalBufferIndex 2 + +// +double bullishBuffer[]; +double bearishBuffer[]; +double signalBuffer[]; + +// +#property indicator_label1 "XBullPower" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#property indicator_label2 "XBearPower" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// #property indicator_label3 "XSignal" +// #property indicator_type3 DRAW_LINE +// #property indicator_color3 clrGold +// #property indicator_style3 STYLE_DOT +// #property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +int xtdBullishCandleCount = 0; +int xtdBearishCandleCount = 0; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i, close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 5) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Bullish Buffer ... + string bullishBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishBuffer, true); + // SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel); + + // + // Bearish Buffer ... + string bearishBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishBuffer, true); + // SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + "Signal " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + // PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, + const double &close[]) +{ + // + // Reset Global Counters ... + xtdBullishCandleCount = 0; + xtdBearishCandleCount = 0; + + // + // Loop through Closes ... + for (int i = bar_index; i <= bar_index + length; i++) + { + for (int j = i + 1; j <= bar_index + length; j++) + { + // + if (close[i] > close[j]) + { + xtdBullishCandleCount++; + } + + // + if (close[i] < close[j]) + { + xtdBearishCandleCount++; + } + } + } + + // + // Bullish Power Buffer ... + bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount); + + // + // Bearish Power Buffer ... + bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount); + + // + // Signal Buffer ... + signalBuffer[bar_index] = bullishBuffer[bar_index] - bearishBuffer[bar_index]; + + // + // Check and Draw Crosses if it's Specified ... + if (drawCrosses) + { + DrawCrosses(bar_index); + } +} + +// +// +double GetState( + int bar_index // Specified Bar Index +) +{ + // + // Check Cross Points ... + // bullishCrossedOverBearish = 2; + // bullishOverBearish = 1; + // bullishCrossedUnderBearish = -2; + // bullishUnderBearish = -1; + // OtherWise = 0; + bool isBullishCrossedOverBearish = IsCrossedOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishCrossedUnderBearish = IsCrossedUnder( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishOverBearish = IsOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishUnderBearish = IsUnder( + bullishBuffer, + bearishBuffer, + bar_index); + + // + double result = X_XTD_NEUTURAL; + if (isBullishCrossedOverBearish) + { + result = X_XTD_BULLISH_CROSSED_OVER_BEARISH; + } + else if (isBullishCrossedUnderBearish) + { + result = X_XTD_BULLISH_CROSSED_UNDER_BEARISH; + } + else if (isBullishOverBearish) + { + result = X_XTD_BULLISH_OVER_BEARISH; + } + else if (isBullishUnderBearish) + { + result = X_XTD_BULLISH_UNDER_BEARISH; + } + else + { + result = X_XTD_NEUTURAL; + } + + // + return result; +} + +// +// Draw Crosses ... +void DrawCrosses( + int bar_index // the bars which required to draw cross arrow on it ... +) +{ + // + double stateValue = GetState(bar_index); + + // + bool isOver = stateValue == 2; + double low = iLow(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + + // + double price = isOver ? low : high; + datetime time = iTime(_Symbol, _Period, bar_index); + ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM; + uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode; + color arrowColor = isOver ? bullishArrowColor : bearishArrowColor; + string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price; + + // + DrawArrow( + 0, + crossName, + 0, + time, + price, + arrowCode, + anchor, + arrowColor); +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtm.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtm.mq5 new file mode 100644 index 0000000..2ee52d1 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xtm.mq5 @@ -0,0 +1,351 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Indicator +// --------------------------------------------- +// Name: XTM +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int maPeriod = 14; // Period +input int maShift = 0; // Shift +input ENUM_MA_METHOD maMethod = MODE_SMA; // Method +input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XTM" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed, CLR_NONE +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + maPeriod, + maShift, + maMethod, + maAppliedTo); + if (maHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, maPeriod); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (maPeriod >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XTM " + "(" + (string)maPeriod + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle; + candle.Init( + _Symbol, + _Period, + bar_index + // + ); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XTM_BULLISH : lineColorIndex == 2 ? X_XTM_BEARISH + : X_XTM_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = showLine ? lineColorIndex : 3; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xts.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xts.mq5 new file mode 100644 index 0000000..e4b7e3a --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xts.mq5 @@ -0,0 +1,548 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTS Oscillator +// --------------------------------------------- +// Name: XTS +// Description: Time Sections Oscillator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTS Oscillator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XTS" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Constants ... +// + +// +// START Inputs ... +// +input group "Current Period"; +input ENUM_APPLIED_PRICE currentAppliedTo = PRICE_CLOSE; // Current Applied To +// +input group "Nearest Period"; +input ENUM_X_PERIOD_METHOD nearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +input ENUM_TIMEFRAMES nearestPeriod = NULL; // Nearest Time Frame +input ENUM_APPLIED_PRICE nearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// +input group "Mediest Period"; +input ENUM_X_PERIOD_METHOD mediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +input ENUM_TIMEFRAMES mediestPeriod = NULL; // Mediest Time Frame +input ENUM_APPLIED_PRICE mediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// +input group "Farest Period"; +input ENUM_X_PERIOD_METHOD farestMethod = X_PERIOD_AUTO; // How to Find Farest Period +input ENUM_TIMEFRAMES farestPeriod = NULL; // Farest Time Frame +input ENUM_APPLIED_PRICE farestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// START Buffers ... +// +// #property indicator_separate_window +#property indicator_chart_window + +// +#property indicator_buffers 4 +// #property indicator_plots 4 +#property indicator_plots 0 + +// +// Current ... +#define currentBufferIndex 0 + +double currentBuffer[]; + +// #property indicator_label1 "XTS C" +// #property indicator_type1 DRAW_LINE +// #property indicator_color1 clrBrown +// #property indicator_style1 STYLE_SOLID +// #property indicator_width1 1 + +// +// Nearest ... +#define nearestBufferIndex 1 + +double nearestBuffer[]; + +// #property indicator_label2 "XTS N" +// #property indicator_type2 DRAW_LINE +// #property indicator_color2 clrAqua +// #property indicator_style2 STYLE_SOLID +// #property indicator_width2 1 + +// +// Mediest ... +#define mediestBufferIndex 2 + +double mediestBuffer[]; + +// #property indicator_label3 "XTS M" +// #property indicator_type3 DRAW_LINE +// #property indicator_color3 clrLime +// #property indicator_style3 STYLE_SOLID +// #property indicator_width3 1 + +// +// Farest ... +#define farestBufferIndex 3 + +double farestBuffer[]; + +// #property indicator_label4 "XTS F" +// #property indicator_type4 DRAW_LINE +// #property indicator_color4 clrLightBlue +// #property indicator_style4 STYLE_SOLID +// #property indicator_width4 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +ENUM_TIMEFRAMES mNearestPeriod = NULL; +ENUM_TIMEFRAMES mMediestPeriod = NULL; +ENUM_TIMEFRAMES mFarestPeriod = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Oscillator ShortName ... + SetOscillatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = 30; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + int maxLength = 30; + + // + // Current ... + ArraySetAsSeries(currentBuffer, true); + SetIndexBuffer(currentBufferIndex, currentBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(currentBufferIndex, currentBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(currentBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Nearest ... + ArraySetAsSeries(nearestBuffer, true); + SetIndexBuffer(nearestBufferIndex, nearestBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(nearestBufferIndex, nearestBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(nearestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Mediest ... + ArraySetAsSeries(mediestBuffer, true); + SetIndexBuffer(mediestBufferIndex, mediestBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(mediestBufferIndex, mediestBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(mediestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Farest ... + ArraySetAsSeries(farestBuffer, true); + SetIndexBuffer(farestBufferIndex, farestBuffer, INDICATOR_CALCULATIONS); + // SetIndexBuffer(farestBufferIndex, farestBuffer, INDICATOR_DATA); + // PlotIndexSetInteger(farestBufferIndex, PLOT_DRAW_BEGIN, maxLength); +} + +// +// Set Oscillator Short Name and also we can define Buffers Labels ... +void SetOscillatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Current ... + CalculateCurrent(bar_index); + + // + // Nearest ... + CalculateNearest(bar_index); + + // + // Mediest ... + CalculateMediest(bar_index); + + // + // Farest ... + CalculateFarest(bar_index); + + // + // Commenting ... + // string comment = GenerateDescriptionComment(); + // Comment(comment); +} + +// +// Current ... +void CalculateCurrent(int bar_index) +{ + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + _Period, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c; + c.Init( + _Symbol, + _Period, + startBarIndex + // + ); + + // + double value = c.GetPrice(currentAppliedTo); + + // + currentBuffer[bar_index] = value; +} + +// +// Nearest ... +void CalculateNearest(int bar_index) +{ + // + if (mNearestPeriod == NULL) + { + // + switch (nearestMethod) + { + // + case X_PERIOD_AUTO: + mNearestPeriod = GetNearestPeriod(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mNearestPeriod = nearestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mNearestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c; + c.Init( + _Symbol, + _Period, + startBarIndex + // + ); + + // + double value = c.GetPrice(nearestAppliedTo); + + // + nearestBuffer[bar_index] = value; +} + +// +// Mediest ... +void CalculateMediest(int bar_index) +{ + // + if (mMediestPeriod == NULL) + { + // + switch (mediestMethod) + { + // + case X_PERIOD_AUTO: + mMediestPeriod = GetMediestPeriod(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mMediestPeriod = mediestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mMediestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c; + c.Init( + _Symbol, + _Period, + startBarIndex + // + ); + + // + double value = c.GetPrice(mediestAppliedTo); + + // + mediestBuffer[bar_index] = value; +} + +// +// Farest ... +void CalculateFarest(int bar_index) +{ + // + if (mFarestPeriod == NULL) + { + // + switch (farestMethod) + { + // + case X_PERIOD_AUTO: + mFarestPeriod = GetLongestPeriod(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mFarestPeriod = farestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mFarestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c; + c.Init( + _Symbol, + _Period, + startBarIndex + // + ); + + // + double value = c.GetPrice(farestAppliedTo); + + // + farestBuffer[bar_index] = value; +} + +// +// Generate Comment ... +string GenerateDescriptionComment() +{ + // + string result = ""; + + // + result += "Nearest : " + EnumToString(mNearestPeriod) + "\n"; + result += "Mediest : " + EnumToString(mMediestPeriod) + "\n"; + result += "Farest : " + EnumToString(mFarestPeriod) + "\n"; + + // + return result; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xzg.mq5 b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xzg.mq5 new file mode 100644 index 0000000..0abb368 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Indicators/x-saherelm.xzg.mq5 @@ -0,0 +1,750 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XZG +// Description: Zogzag Implementation ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XZG Indicator" +#property strict + +// +#define ShortName "XZG" + +// +// DEFINITIONS ... +enum ENUM_X_ZG_SEARCH_MODE +{ + X_ZG_SEARCH_EXTREMUM = 0, // searching for the first extremum + X_ZG_SEARCH_PEAK = 1, // searching for the next ZigZag peak + X_ZG_SEARCH_VALE = -1 // searching for the next ZigZag vale +}; + +// +// How to Calculate Up and Down Price ... +enum ENUM_X_ZG_PRICE_MODE +{ + // + X_ZG_PRICE_HIGH_LOW_MODE = 1, + X_ZG_PRICE_OPEN_CLOSE_MODE = 2, +}; + +// +// INPUT ... + +// +input group "Market"; +input int depth = 12; // Depth +input int deviation = 5; // Deviation +input int backStep = 3; // Back Step +input ENUM_X_ZG_PRICE_MODE mode = X_ZG_PRICE_HIGH_LOW_MODE; // Mode + +// +input group "Presentation"; +input bool showZigZag = true; // Show ZigZag +input bool showPeaksAndVales = true; // Show Peaks and Vales + +// +// BUFFERS ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 6 +#property indicator_plots 4 + +// +// ZigZag ... + +// +#define mainBufferIndex 0 +#define mainBufferPlotIndex 0 +double mainBuffer[]; + +#define mainColorBufferIndex 1 +double mainColorBuffer[]; + +// +#property indicator_label1 "XZG Main" +#property indicator_type1 DRAW_COLOR_SECTION +#property indicator_color1 CLR_NONE, clrRoyalBlue, clrSaddleBrown +#property indicator_width1 2 + +// +// Highs ... + +// +// ZigZag Pointer or Line Indicator ... +#define arrowBufferIndex 2 +#define arrowBufferPlotIndex 1 +double arrowBuffer[]; + +// +#define arrowColorBufferIndex 3 +double arrowColorBuffer[]; + +// +#property indicator_label2 "XZG PV" +#property indicator_type2 DRAW_COLOR_ARROW +#property indicator_color2 CLR_NONE, clrAqua, clrMagenta +#property indicator_width2 1 + +// +#define highsBufferIndex 4 +double highsBuffer[]; + +// +// Lows ... + +// +#define lowsBufferIndex 5 +double lowsBuffer[]; + +// +// VARIABLES ... + +// +int mRecalc = 3; // Number of last extremes for recalculation + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + double mZGHigh[]; + double mZGLow[]; + if (mode == X_ZG_PRICE_OPEN_CLOSE_MODE) + { + // + ArrayCopy( + mZGHigh, + open + // + ); + + // + ArrayCopy( + mZGLow, + close + // + ); + } + else + { + // + ArrayCopy( + mZGHigh, + high + // + ); + + // + ArrayCopy( + mZGLow, + low + // + ); + } + + // + int zigZagResult = CalcukateZigZag( + prev_calculated, + rates_total, + mZGHigh, + mZGLow + // + ); + + // + if (zigZagResult != rates_total) + { + return zigZagResult; + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + depth > 0 && + deviation > 0 && + backStep > 0 + // + ; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Main ... + + // + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + SetIndexBuffer(mainColorBufferIndex, mainColorBuffer, INDICATOR_COLOR_INDEX); + + // + PlotIndexSetInteger(mainBufferPlotIndex, PLOT_SHOW_DATA, showZigZag); + PlotIndexSetInteger(mainBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(mainBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Arrow ... + + // + SetIndexBuffer(arrowBufferIndex, arrowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW, 159); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW_SHIFT, 0); + PlotIndexSetDouble(arrowBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Arrow Color ... + SetIndexBuffer(arrowColorBufferIndex, arrowColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Highs ... + SetIndexBuffer(highsBufferIndex, highsBuffer, INDICATOR_CALCULATIONS); + + // + // Lows ... + SetIndexBuffer(lowsBufferIndex, lowsBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculating Zig Zag ... +int CalcukateZigZag( + const int prev_calculated, + const int rates_total, + double &high[], + double &low[] + // +) +{ + // + if (rates_total < 100) + { + return 0; + } + + // + // Define Variables ... + int i = 0; + + // + int start = 0; + int extreme_counter = 0; + int extreme_search = X_ZG_SEARCH_EXTREMUM; + int shift = 0; + int back = 0; + int last_high_pos = 0; + int last_low_pos = 0; + + // + double val = 0; + double res = 0; + double curlow = 0; + double curhigh = 0; + double last_high = 0; + double last_low = 0; + + // + double colorIDX = 0; + double lastZigZagValue = 0; + + // + // Initializing ... + if (prev_calculated == 0) + { + // + ArrayInitialize(mainBuffer, 0); + ArrayInitialize(highsBuffer, 0); + ArrayInitialize(lowsBuffer, 0); + + // + start = depth; + } + + // + // Already Calculated Before ... + if (prev_calculated > 0) + { + // + i = rates_total - 1; + + // + // Searching for the third X_ZG_SEARCH_EXTREMUM from the last UnComplete Bar ... + while (extreme_counter < mRecalc && i > rates_total - 100) + { + // + res = mainBuffer[i]; + if (res != 0) + { + extreme_counter++; + } + + // + i--; + } + + // + i++; + start = i; + + // + // What type of X_ZG_SEARCH_EXTREMUM we Search for ... + if (lowsBuffer[i] != 0) + { + // + curlow = lowsBuffer[i]; + extreme_search = X_ZG_SEARCH_PEAK; + } + else + { + // + curhigh = highsBuffer[i]; + extreme_search = X_ZG_SEARCH_VALE; + } + + // + // Clear Values ... + for (i = start + 1; i < rates_total && !IsStopped(); i++) + { + // + mainBuffer[i] = 0; + lowsBuffer[i] = 0; + highsBuffer[i] = 0; + } + } + + // + // Search for High and Low Extremes ... + for (shift = start; shift < rates_total && !IsStopped(); shift++) + { + // + // Low ... + val = low[Lowest(low, depth, shift)]; + if (val == last_low) + { + val = 0; + } + else + { + // + last_low = val; + + // + if ((low[shift] - val) > deviation * _Point) + { + val = 0; + } + else + { + // + for (back = 1; back <= backStep; back++) + { + // + res = lowsBuffer[shift - back]; + if ((res != 0) && (res > val)) + { + lowsBuffer[shift - back] = 0; + } + } + } + } + + // + if (low[shift] == val) + { + lowsBuffer[shift] = val; + } + else + { + lowsBuffer[shift] = 0; + } + + // + // High ... + val = high[Highest(high, depth, shift)]; + if (val == last_high) + { + val = 0; + } + else + { + // + last_high = val; + + // + if ((val - high[shift]) > deviation * _Point) + { + val = 0; + } + else + { + // + for (back = 1; back <= backStep; back++) + { + // + res = highsBuffer[shift - back]; + if ((res != 0) && (res < val)) + { + highsBuffer[shift - back] = 0; + } + } + } + } + + // + if (high[shift] == val) + { + highsBuffer[shift] = val; + } + else + { + highsBuffer[shift] = 0; + } + } + + // + // Set Last Value ... + if (extreme_search == 0) // Undefined Values ... + { + // + last_low = 0; + last_high = 0; + } + else + { + // + last_low = curlow; + last_high = curhigh; + } + + // + // Final Selection of Extreme Points for ZigZag ... + for (shift = start; shift < rates_total && !IsStopped(); shift++) + { + // + res = 0; + + // + switch (extreme_search) + { + // + case X_ZG_SEARCH_EXTREMUM: + // + if (last_low == 0 && last_high == 0) + { + // + if (highsBuffer[shift] != 0) + { + // + last_high_pos = shift; + last_high = high[shift]; + + // + extreme_search = X_ZG_SEARCH_VALE; + + // + mainBuffer[shift] = last_high; + + // + res = 1; + } + + // + if (lowsBuffer[shift] != 0) + { + // + last_low_pos = shift; + last_low = low[shift]; + + // + extreme_search = X_ZG_SEARCH_PEAK; + + // + mainBuffer[shift] = last_low; + + // + res = 1; + } + } + break; + + // + case X_ZG_SEARCH_PEAK: + // + if (lowsBuffer[shift] != 0 && lowsBuffer[shift] < last_low && highsBuffer[shift] == 0) + { + // + mainBuffer[last_low_pos] = 0; + + // + last_low_pos = shift; + last_low = lowsBuffer[shift]; + + // + mainBuffer[shift] = last_low; + + // + res = 1; + } + + // + if (highsBuffer[shift] != 0 && lowsBuffer[shift] == 0) + { + // + last_high_pos = shift; + last_high = highsBuffer[shift]; + + // + mainBuffer[shift] = last_high; + + // + extreme_search = X_ZG_SEARCH_VALE; + + // + res = 1; + } + break; + + // + case X_ZG_SEARCH_VALE: + // + if (highsBuffer[shift] != 0 && highsBuffer[shift] > last_high && lowsBuffer[shift] == 0) + { + // + mainBuffer[last_high_pos] = 0; + + // + last_high_pos = shift; + last_high = highsBuffer[shift]; + + // + mainBuffer[shift] = last_high; + } + + // + if (lowsBuffer[shift] != 0 && highsBuffer[shift] == 0) + { + // + last_low_pos = shift; + last_low = lowsBuffer[shift]; + + // + mainBuffer[shift] = last_low; + + // + extreme_search = X_ZG_SEARCH_PEAK; + } + break; + } + + // + double iZigZagForColor = lastZigZagValue; + double iZigZag = mainBuffer[shift]; + if (iZigZag == 0 && lastZigZagValue != 0) + { + arrowBuffer[shift] = lastZigZagValue; + } + else if (iZigZag != 0) + { + // + lastZigZagValue = iZigZag; + arrowBuffer[shift] = lastZigZagValue; + } + + // + colorIDX = + lastZigZagValue > iZigZagForColor + ? 1 + : lastZigZagValue < iZigZagForColor + ? 2 + : colorIDX; + + // + mainColorBuffer[shift] = showZigZag ? colorIDX : 0; + arrowColorBuffer[shift] = showPeaksAndVales ? colorIDX : 0; + } + + // + return rates_total; +} + +// +// TOOLS ... + +// +// Search for the index of the highest bar ... +int Highest( + const double &mArray[], + const int mDepth, + const int mStart // +) +{ + // + int result = 0; + + // + if (mStart < 0) + { + return result; + } + + // + double max = mArray[mStart]; + result = mStart; + + // + // Start searching ... + for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--) + { + // + if (mArray[i] > max) + { + // + result = i; + max = mArray[i]; + } + } + + // + // Return index of the highest bar + return result; +} + +// +// Search for the index of the lowest bar ... +int Lowest( + const double &mArray[], + const int mDepth, + const int mStart // +) +{ + // + int result = 0; + + // + if (mStart < 0) + { + return result; + } + + // + double min = mArray[mStart]; + result = mStart; + + // + // Start searching ... + for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--) + { + // + if (mArray[i] < min) + { + // + result = i; + min = mArray[i]; + } + } + + // + // Return index of the lowest bar + return result; +} diff --git a/MQLTestWorkspace/BKPS/14030309/JsModules/x-color.tools.js b/MQLTestWorkspace/BKPS/14030309/JsModules/x-color.tools.js new file mode 100644 index 0000000..c3ac5f9 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/JsModules/x-color.tools.js @@ -0,0 +1,506 @@ +/** + * XColor Tools Module ... + * a module for handle colorify text contents in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Module Imports ... +const XValueTools = require("./x-value.tools"); +//#endregion + +// +//#region Constants ... +/** + * these are available style which can applied to an string ... + */ +const AVAILABLE_STYLES = { + // + Bold: "\x1b[1m", + Dim: "\x1b[2m", + Underlined: "\x1b[4m", + Blink: "\x1b[5m", + ReverseFandB: "\x1b[7m", + Hidden: "\x1b[8m", + // + // Commonly used for reset all Styles ... + Reset: "\x1b[0m" +}; + +/** + * these are available foreground colors which can applied to an string ... + */ +const AVAILABLE_FOREGROUND_COLORS = { + Default: "\x1b[39m", + Black: "\x1b[30m", + Red: "\x1b[31m", + Green: "\x1b[32m", + Yellow: "\x1b[33m", + Blue: "\x1b[34m", + Magenta: "\x1b[35m", + Cyan: "\x1b[36m", + LightGray: "\x1b[37m", + DarkGray: "\x1b[90m", + LightRed: "\x1b[91m", + LightGreen: "\x1b[92m", + LightYellow: "\x1b[93m", + LightBlue: "\x1b[94m", + LightMagenta: "\x1b[95m", + LightCyan: "\x1b[96m", + White: "\x1b[97m", +}; + +/** + * these are available background colors which can applied to an string ... + */ +const AVAILABLE_BACKGROUND_COLORS = { + Default: "\x1b[49m", + Black: "\x1b[40m", + Red: "\x1b[41m", + Green: "\x1b[42m", + Yellow: "\x1b[43m", + Blue: "\x1b[44m", + Magenta: "\x1b[45m", + Cyan: "\x1b[46m", + LightGray: "\x1b[47m", + DarkGray: "\x1b[100m", + LightRed: "\x1b[101m", + LightGreen: "\x1b[102m", + LightYellow: "\x1b[103m", + LightBlue: "\x1b[104m", + LightMagenta: "\x1b[105m", + LightCyan: "\x1b[106m", + White: "\x1b[107m", +}; + +/** + * these are available style names, which exports from module and + * users can use them ... + */ +const STYLE_NAMES = { + Bold: "Bold", + Dim: "Dim", + Underlined: "Underlined", + Blink: "Blink", + ReverseFandB: "ReverseFandB", + Hidden: "Hidden", + Reset: "Reset", +}; + +/** + * these are available color names, which exports from module and + * users can use them ... + */ +const COLOR_NAMES = { + Default: "Default", + Black: "Black", + Red: "Red", + Green: "Green", + Yellow: "Yellow", + Blue: "Blue", + Magenta: "Magenta", + Cyan: "Cyan", + LightGray: "LightGray", + DarkGray: "DarkGray", + LightRed: "LightRed", + LightGreen: "LightGreen", + LightYellow: "LightYellow", + LightBlue: "LightBlue", + LightMagenta: "LightMagenta", + LightCyan: "LightCyan", + White: "White", +}; +//#endregion + +// +//#region Actions ... +/** + * apply specified style and color on a content ... + * + * @param {string} content specified content for styling ... + * @param {string} color specific color name for using to styling ... + * @param {string} style soecufic style name to use ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} styled content ... + */ +function apply( + content, + color, + style, + toForeground = true, + toBackground = false +) { + // + let result = content; + + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return result; + } + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}${result}${AVAILABLE_STYLES.Reset}`; + } + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}${result}${AVAILABLE_STYLES.Reset}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}${result}${AVAILABLE_STYLES.Reset}`; + } + +} + +/** + * apply specific style on a content ... + * + * @param {string} content specific content which going to styled ... + * @param {string} style a member of STYLE_NAMES which specified that which style going to applied to content ... + * @returns {string} styled content ... + */ +function applyStyle(content, style) { + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return content; + } + + // + let eStyle = AVAILABLE_STYLES[style]; + if (eStyle === undefined) { + return content; + } + + // + return `${eStyle}${content}${AVAILABLE_STYLES.Reset}`; +} + +/** + * apply specific foreground color on a content ... + * + * @param {string} content specific content which going to colorified ... + * @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ... + * @returns {string} colorified content ... + */ +function applyForegroundColor(content, color) { + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return content; + } + + // + let eColor = AVAILABLE_FOREGROUND_COLORS[color]; + if (eColor === undefined) { + return content; + } + + // + return `${eColor}${content}${AVAILABLE_STYLES.Reset}`; +} + +/** + * apply specific background color on a content ... + * + * @param {string} content specific content which going to colorified ... + * @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ... + * @returns {string} colorified content ... + */ +function applyBackgroundColor(content, color) { + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return content; + } + + // + let eColor = AVAILABLE_BACKGROUND_COLORS[color]; + if (eColor === undefined) { + return content; + } + + // + return `${eColor}${content}${AVAILABLE_STYLES.Reset}`; +} + +/** + * generate style and color applier expression ... + * + * @param {string} color specific color name for using to styling ... + * @param {string} style soecufic style name to use ... + * @param {boolean} reset close applier string by reset styles ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} style and color applier string ... + */ +function getApplier( + style = "", + color = "", + reset = false, + toForeground = true, + toBackground = false +) { + // + let result = ""; + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}`; + } + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}`; + } + + // + if ( + !!reset && + result.length > 0 + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * generate style applier expression ... + * + * @param {string} style soecufic style name to use ... + * @param {boolean} reset close applier string by reset styles ... + * @returns {string} style applier string ... + */ +function getStyleApplier( + style = "", + reset = false +) { + // + let result = ""; + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}`; + } + + // + if ( + !!reset && + result.length > 0 + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * generate color applier expression ... + * + * @param {string} color specific color name for using to styling ... + * @param {boolean} reset close applier string by reset styles ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} color applier string ... + */ +function getColorApplier( + color = "", + reset = false, + toForeground = true, + toBackground = false +) { + // + let result = ""; + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}`; + } + + // + if ( + !!reset && + result.length > 0 + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * colorified specific content ... + * + * @param {string} content specified content for styling ... + * @param {string} color specific color name for using to styling ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} + */ +function colorifyContent( + content = "", + color = "", + toForeground = true, + toBackground = false +) { + // + let result = content; + + // + if (!XValueTools.isValidArg(content)) { + return result; + } + + // + // Finde Colors ... + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}${result}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}${result}`; + } + + // + if ( + result.length > 0 + && ( + XValueTools.isValidArg(eFColor) || + XValueTools.isValidArg(eBColor) + ) + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * apply style on specific content ... + * + * @param {string} content specified content for styling ... + * @param {string} style soecufic style name to use ... + * @returns {string} + */ +function stylifiyContent( + content = "", + style = "", +) { + // + let result = content; + + // + if (!XValueTools.isValidArg(content)) { + return result; + } + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}${result}`; + } + + // + if ( + result.length > 0 + && XValueTools.isValidArg(eStyle) + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + STYLE_NAMES, + COLOR_NAMES, + // + apply, + applyStyle, + getApplier, + getColorApplier, + getStyleApplier, + colorifyContent, + stylifiyContent, + applyForegroundColor, + applyBackgroundColor, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/JsModules/x-file.tools.js b/MQLTestWorkspace/BKPS/14030309/JsModules/x-file.tools.js new file mode 100644 index 0000000..a752fc2 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/JsModules/x-file.tools.js @@ -0,0 +1,890 @@ +/** + * XFile Tools Module ... + * a module for handle all file/folder manipulating task in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Module Imports ... +const fs = require('fs'); +const os = require('os'); +const Path = require('path'); +const http = require('http'); +const https = require('https'); +const XValueTools = require('./x-value.tools'); +//#endregion + +// +//#region Constants ... +/** + * current os path separators ... + */ +const PathSeparator = Path.sep; + +/** + * current directory ... + */ +const CurrentDir = __dirname; +//#endregion + +// +//#region Actions ... +// +//#region Global ... +/** + * retrieve a path status ... + * + * @param {string} path a path value to check ... + * @returns an stat object ... + */ +function getStatus(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return undefined; + } + + // + return fs.statSync(path); +} + +/** + * retrieve user's Home path ... + * + * @returns {string} a path ... + */ +function getHomePath() { + return os.homedir(); +} +//#endregion + +// +//#region Path ... +/** + * retrieve the base name of specific address path ... + * + * @param {string} path address of file or folder ... + * @returns string ... + */ +function basename(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return ''; + } + + // + const result = Path.basename(path); + return result; +} + +/** + * join several path segments together ... + * + * @param {...string} path path params ... + * @returns a joined paths ... + */ +function joinPath(...path) { + return Path.join(...path); +} + +/** + * resolve a relative path to absolute ... + * + * @param {string[]} path a path value to check ... + * @returns {string} + */ +function resolvePath(...path) { + return Path.resolve(...path); +} +//#endregion + +// +//#region File ... +/** + * determines a path destination is a file or not ... + * + * @param {string} path a path value to check ... + * @returns a boolean value ... + */ +function isFileExists(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return false; + } + + // + try { + const stat = getStatus(path); + if (!stat) { + return false; + } + + // + return stat.isFile(); + } catch { + return false; + } +} + +/** + * remove a file ... + * + * @param {string} path a file path ... + * @returns {Promise} action done or not ... + */ +function removeFile(path = '') { + return new Promise((resolve) => { + // + if (!isFileExists(path)) { + resolve(false); + } + + // + fs.unlink(path, (err) => { + // + if (err) { + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * copy a file to destination path ... + * + * @param {string} source source file path ... + * @param {string} dest dest folder path ... + * @returns {Promise} action done or not ... + */ +function copyFile( + source = '', + dest = '' +) { + return new Promise((resolve) => { + // + if ( + !isFileExists(source) || + !isDirectoryExists(dest) + ) { + resolve(false); + return; + } + + // + const destFilePath = Path.join(dest, Path.basename(source)); + fs.copyFile(source, destFilePath, (err) => { + // + if (err) { + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * reading specified file content ... + * + * @param {string} path a file path ... + * @returns {Promise} file content ... + */ +function readFile(path = '') { + return new Promise((resolve) => { + // + if (!isFileExists(path)) { + resolve(''); + return; + } + + // + fs.readFile(path, 'utf8', (err, content) => { + // + if (err) { + resolve(undefined); + return; + } + + // + resolve(content); + }); + }); +} + +/** + * write content to a file ... + * + * @param {string} path a file path ... + * @param {string} content the content which going to write to the file ... + * @param {bool} overwrite determines file overwrite if exists ... + * @returns {Promise} action done or not ... + */ +function writeFile( + path = '', + content = '', + overwrite = true +) { + return new Promise((resolve) => { + // + if (isFileExists(path) && !overwrite) { + // + resolve(false); + return; + } + + // + // Normalize Content ... + content = XValueTools.isValidArg(content) ? + content : + ''; + + // + fs.writeFile(path, content, (err) => { + // + if (err) { + // + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * create a file ... + * + * @param {string} path file path ... + * @param {string} fileName file name ... + * @returns {Promise} action done or not ... + */ +function createFile( + path = '', + fileName = '' +) { + return new Promise((resolve) => { + // + const filePath = Path.join(path, fileName); + if ( + isFileExists(filePath) || + !XValueTools.isValidArg(path) || + !XValueTools.isValidArg(fileName) + ) { + // + resolve(false); + return; + } + + // + fs.writeFile(filePath, '', (err) => { + // + if (err) { + // + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * remove a file name extension ... + * + * @param {string} name + * @returns {string} name without extension ... + */ +function removeFileExtension(name = '') { + return name.substring(0, name.lastIndexOf('.')) || name; +} + +/** + * retrieve a file extension ... + * + * @param {string} path a path which locate a file ... + * @returns {string} + */ +function getFileExtension(path = '') { + // + let result = ""; + + // + // Validate Arg ... + if ( + !XValueTools.isValidArg(path) + || !isFileExists(path) + ) { + return result; + } + + // + // Retrieve just file name ... + const fileName = basename(path); + result = fileName.replace( + removeFileExtension(fileName), + "" + ); + + // + return result; +} + +/** + * retrieve all files list recursively from specific path ... + * + * @param {string} path a source folder path ... + * @param {string[]} extensions which file extensions need to be listed, live empty for all files ... + * @returns {Promise} + */ +async function getRecursiveFilesList( + path = "", + extensions = [] +) { + // + let result = []; + + // + // Validate Args ... + if ( + !XValueTools.isValidArg(path) + || !isDirectoryExists(path) + ) { + return result; + } + + // + const contents = await getDirectoryContents(path); + for (const item of contents) { + // + const itemPath = joinPath( + path, + item + ); + + // + const isItemFile = isFileExists(itemPath); + if (isItemFile) { + // + const itemFileExtension = getFileExtension(itemPath); + const isFileInSupportedExtensions = + extensions === undefined || extensions.length === 0 + ? true + : extensions.includes(itemFileExtension) + ; + if (isFileInSupportedExtensions) { + result.push(itemPath); + } + } else if (isDirectoryExists(itemPath)) { + // + const itemPathFiles = await getRecursiveFilesList(itemPath, extensions); + result.push(...itemPathFiles); + } + } + + // + return result; +} + +/** + * Extract Specific files from a folder and it's content ... + * + * @param {string} path Folder Path ... + * @returns + */ +async function extractFiles(path = "", ext = []) { + // + const result = []; + + // + if (!ext || ext.length == 0) { + return result; + } + + // + const pathContent = await getDirectoryContents(path); + if (!pathContent || pathContent.length == 0) { + return result; + } + + // + // Loop through Content ... + for (const c of pathContent) { + // + // Prepare full path ... + const cPath = joinPath(path, c); + + // + // check content path is file or not ... + const isCFile = isFileExists(cPath); + const isCDirectory = isDirectoryExists(cPath); + if (isCFile) { + // + // Check it is MQL file or not ... + const cExt = getFileExtension(cPath); + if (ext.includes(cExt)) { + result.push(cPath); + } + } else if (isCDirectory) { + // + const destFolderName = basename(cPath); + const isExcluded = excludeWorkspaceFolders.includes(destFolderName); + if (isExcluded) { + continue; + } + + // + const cFiles = await extractFiles(cPath, ext); + if (cFiles && cFiles.length > 0) { + result.push(...cFiles); + } + } + } + + // + return result; +} +//#endregion + +// +//#region Directory ... +/** + * create a directory ... + * + * @param {string} path destination path including dir name ... + * @param {boolean} recursive create directories recursively ... + * @returns action done or not ... + */ +function createDirectory( + path = '', + recursive = true +) { + // + let result = false; + + // + if ( + isDirectoryExists(path) || + !XValueTools.isValidArg(path) + ) { + return false; + } + + // + try { + // + fs.mkdirSync(path, { recursive: recursive }); + result = true; + return result; + } catch { + return false; + } +} + +/** + * remove a directory ... + * + * @param {string} path destination path including dir name ... + * @param {boolean} recursive removes directories recursively ... + * @returns {Promise} action done or not ... + */ +function removeDirectory( + path = '', + recursive = false +) { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve(false); + return; + } + + // + fs.rm(path, { + recursive + }, (err) => { + // + if (err) { + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * determines a path destination is a directory or not ... + * + * @param {string} path a folder path ... + * @returns represent destnation path is Directory or not ... + */ +function isDirectoryExists(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return false; + } + + // + try { + // + const isExists = fs.existsSync(path); + if (!isExists) { + return false; + } + + // + const stat = getStatus(path); + if (!stat) { + return false; + } + + // + const result = stat.isDirectory(); + return result; + } catch { + return false; + } +} + +/** + * retrieve a directory content ... + * + * @param {string} path a folder path ... + * @returns {Promise} a collection of folder files ... + */ +function getDirectoryContents(path = '') { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve([]); + return; + } + + // + fs.readdir(path, (err, content) => { + // + if (err) { + resolve([]); + return; + } + + // + resolve(content); + }); + }); +} + +/** + * retrieve a directory files ... + * + * @param {string} path a folder path ... + * @returns {Promise} a collection of folder files ... + */ +function getDirectoryFiles( + path = '', + containsHiddenFiles = false +) { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve([]); + return; + } + + // + fs.readdir(path, (err, content) => { + // + if (err) { + resolve([]); + return; + } + + // + if (!containsHiddenFiles) { + content = content.filter(c => !c.startsWith('.')); + } + + // + const result = []; + content + .forEach(c => { + // + const cPath = Path.join(path, c); + if (isFileExists(cPath)) { + result.push(c); + } + }); + + // + resolve(result); + }); + }); +} + +/** + * retrieve a directory folders ... + * + * @param {string} path a folder path ... + * @returns {Promise} a collection of folder names ... + */ +function getDirectoryFolders(path = '') { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve([]); + return; + } + + // + fs.readdir(path, (err, content) => { + // + if (err) { + resolve([]); + return; + } + + // + const result = []; + content.forEach(c => { + // + const cPath = Path.join(path, c); + if (isDirectoryExists(cPath)) { + result.push(c); + } + }); + + // + resolve(result); + }); + }); +} + +/** + * copy a folder with all of it's content to dest ... + * + * @param {string} source source folder path ... + * @param {string} dest dest folder path ... + * @returns {Promise} action done or not ... + */ +async function copyFolder( + source = '', + dest = '' +) { + // + if ( + !isDirectoryExists(source) || + !XValueTools.isValidArg(dest) || + !XValueTools.isValidArg(source) + ) { + return false; + } + + // + const folderName = Path.basename(source); + const destPath = Path.join(dest, folderName); + + // + // Create Dest Path folder if not exists ... + if (!isDirectoryExists(destPath)) { + // + let result = createDirectory(destPath, true); + if (!result) { + return false; + } + } + + // + // Files ... + const files = await getDirectoryFiles(source); + if (files && files.constructor === Array && files.length > 0) { + // + const filesPromises = files.map(file => copyFile(Path.join(source, file), destPath)); + const filesResult = (await Promise.all(filesPromises)).every(r => !!r); + if (!filesResult) { + return false; + } + } + + // + // Folders ... + const folders = await getDirectoryFolders(source); + if (folders && folders.constructor === Array && folders.length > 0) { + // + const folderPromises = folders.map(folder => copyFolder(Path.join(source, folder), destPath)); + const filesResult = (await Promise.all(folderPromises)).every(r => !!r); + if (!filesResult) { + return false; + } + } + + // + return true; +} +//#endregion + +// +//#region Downloader ... +/** + * download a file from specific url and store it ... + * + * @param {string} filepath the file name and path which required to put download file on it ... + * @param {string} url the web url for downloading ... + */ +function download(filepath, url) { + // + // Validate Args ... + if ( + !XValueTools.isValidArg(url) + || !XValueTools.isValidURL(url) + || !XValueTools.isValidArg(filepath) + ) { + return; + } + + // + var file = fs.createWriteStream(filepath); + + // + if (url.startsWith('https:')) { + https.get(url, function (response) { + response.pipe(file); + }); + } else if (url.startsWith('http:')) { + http.get(url, function (response) { + response.pipe(file); + }); + } +} +//#endregion + +// +//#region JSON ... +/** + * read and parse a JSON content from a file ... + * + * @param {string} path source file path ... + * @returns {any} + */ +function readJSON(path = "") { + // + // Validate Args ... + if (!isFileExists(path)) { + return undefined; + } + + // + let result = undefined; + try { + result = require(path); + } catch { + result = undefined; + } + + // + return result; +} + +/** + * write a JSON Object content into a file ... + * + * @param {string} path dest file path ... + * @param {any} content an object which required to write to file ... + * @returns {Promise} + */ +async function writeJSON( + path = "", + content = undefined +) { + // + let result = false; + + // + // Validate Args ... + if (!XValueTools.isValidArg(path)) { + return result; + } + + // + // Normallize Content ... + if (content === undefined) { + content = {}; + } + + // + const contentString = XValueTools.beautifyJSON(content); + + // + result = await writeFile( + path, + contentString, + true + ); + + // + return result; +} +//#endregion +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + CurrentDir, + PathSeparator, + + // + getStatus, + getHomePath, + + // + basename, + joinPath, + resolvePath, + + // + download, + + // + readJSON, + writeJSON, + + // + copyFile, + readFile, + writeFile, + createFile, + removeFile, + isFileExists, + getFileExtension, + removeFileExtension, + getRecursiveFilesList, + extractFiles, + + // + copyFolder, + createDirectory, + removeDirectory, + createDirectory, + removeDirectory, + isDirectoryExists, + isDirectoryExists, + getDirectoryFiles, + getDirectoryFolders, + getDirectoryContents, +}; +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/JsModules/x-shell.tools.js b/MQLTestWorkspace/BKPS/14030309/JsModules/x-shell.tools.js new file mode 100644 index 0000000..0ee13de --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/JsModules/x-shell.tools.js @@ -0,0 +1,219 @@ +/** + * XShell Tools Module ... + * a module for handling shell actions and retrieve OS Info in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Imports ... +const os = require('os'); +const process = require('process'); +const { exec } = require("child_process"); +const XFileTools = require('./x-file.tools'); +//#endregion + +// +//#region Constants ... +// +const OS = { + Aix: 'aix', + Darwin: 'darwin', + FreeBSD: 'freebsd', + Linux: 'linux', + OpenBSD: 'openbsd', + SnOS: 'sunos', + Windows: 'win32' +}; + +// +const isWindows = process.platform === OS.Windows; +//#endregion + +// +//#region Actions ... +// +//#region Pure shell commands ... +/** + * execute a command using NodeJS on shell ... + * + * @param {string} cmd command to execute ... + * @param {string} cwd working directory ... + * + * @returns Promise instance ... + */ +function execute(cmd, cwd) { + return new Promise((resolve, reject) => { + // + if (!cmd || cmd.toString().length === 0 || (cwd && !XFileTools.isDirectoryExists(cwd))) { + reject('invalid args ...'); + return; + } + + // + exec(cmd, { cwd }, (err, result, stdError) => { + // + if (err) { + reject(err); + return; + } + + // + if (stdError) { + // + // reject(stdError); + // return; + } + + // + resolve(result); + }); + }); +}; + +/** + * determines a command exists on host or not ... + * + * @param {string} name specific command name ... + * + * @returns boolean Promise ... + */ +function checkCommandExists(name) { + return new Promise(resolve => { + // + if (!name) { + resolve(false); + return; + } + + // + const cmd = isWindows ? `${name} >nul 2>&1` : `type ${name} >/dev/null 2>&1`; + execute(cmd).then(result => { + resolve(true); + }) + .catch(err => { + resolve(false); + }); + }); +} +//#endregion + +// +//#region required commands state ... +/** + * check al required commands exists or not ... + * + * @returns + */ +async function isRequiredCommandsExists() { + // + let result = false; + + // + // const isTarExists = await isTarCommandExists(); + // const isCatExists = await isCatCommandExists(); + // const isGrepExists = await isGrepCommandExists(); + // const isSedExists = await isSedCommandExists(); + const isNpmExists = await isNpmCommandExists(); + const isNgExists = await isNgCommandExists(); + const isIonicExists = await isIonicCommandExists(); + const isCordovaExists = await isCordovaCommandExists(); + + // + result = isNpmExists + && isNgExists + && isIonicExists + && isCordovaExists + ; + + // + return result; +} + +/** + * retrieve required commands state object ... + * + * @returns + */ +async function getRequiredCommandsStates() { + // + const result = {}; + + // + // const isTarExists = await isTarCommandExists(); + // const isCatExists = await isCatCommandExists(); + // const isGrepExists = await isGrepCommandExists(); + // const isSedExists = await isSedCommandExists(); + const isNpmExists = await isNpmCommandExists(); + const isNgExists = await isNgCommandExists(); + const isIonicExists = await isIonicCommandExists(); + const isCordovaExists = await isCordovaCommandExists(); + + // + result['npm'] = isNpmExists; + result['ng'] = isNgExists; + result['ionic'] = isIonicExists; + result['cordova'] = isCordovaExists; + + // + return result; +} +//#endregion + +// +//#region Commonly used Command Checkers ... +/** + * determines npm command exists or not ... + * + * @returns + */ +function isNpmCommandExists() { + return checkCommandExists('npm'); +} + +/** + * determines ng command exists or not ... + * + * @returns + */ +function isNgCommandExists() { + return checkCommandExists('ng'); +} + +/** + * determines ionic command exists or not ... + * + * @returns + */ +function isIonicCommandExists() { + return checkCommandExists('ionic'); +} + +/** + * determines cordova command exists or not ... + * + * @returns + */ +function isCordovaCommandExists() { + return checkCommandExists('cordova'); +} +//#endregion +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + execute, + checkCommandExists, + isRequiredCommandsExists, + getRequiredCommandsStates, + + // + isNgCommandExists, + isIonicCommandExists, + isCordovaCommandExists, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/JsModules/x-type-detector.tools.js b/MQLTestWorkspace/BKPS/14030309/JsModules/x-type-detector.tools.js new file mode 100644 index 0000000..86ed3d8 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/JsModules/x-type-detector.tools.js @@ -0,0 +1,268 @@ +/** + * DataType Tools Module ... + * a module for manipulate and detect supported data types in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Constants ... +/** + * all supported data types ... + */ +const DataTypes = { + Null: 'null', + Date: 'date', + Array: 'array', + Object: 'object', + String: 'string', + Number: 'number', + Unknown: 'unknown', + Boolean: 'boolean', + Function: 'function', + Undefined: 'undefined', +}; +//#endregion + +// +//#region Actions ... +/** + * detect type of a content ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function getType(value) { + // + const type = typeof value; + + // + let result = DataTypes.Unknown; + let dateIdentifier = '[object Date]'; + let constructor = value && value.constructor ? + value.constructor.toString() : + ''; + + // + switch (type) { + // + case 'undefined': + result = DataTypes.Undefined; + break; + + // + case 'boolean': + result = DataTypes.Boolean; + break; + + // + case 'string': + result = DataTypes.String; + break; + + // + case 'number': + result = DataTypes.Number; + break; + + // + case 'function': + result = DataTypes.Function; + break; + + // + case 'object': + // + // Null ... + if (value === null) { + result = DataTypes.Null; + } else + // + // Array ... + if (Array.isArray(value)) { + result = DataTypes.Array; + } else + // + // Data ... + if ( + value instanceof Date || + isFunction(value.getMonth) || + constructor.includes(dateIdentifier) || + Object.prototype.toString.call(value) === dateIdentifier + ) { + result = DataTypes.Date; + } else + // + // Object ... + { + result = DataTypes.Object; + } + break; + + // + default: + result = DataTypes.Unknown; + break; + } + + // + return result; +} + +/** + * retrieve an object constructor ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function getConstructor(value) { + // + const result = value && value.constructor ? + value.constructor.toString() : + ''; + + // + return result; +} + +/** + * retrieve an object prototype ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function getPrototype(value) { + // + const result = value ? + Object.prototype.toString.call(value) : + ''; + + // + return result; +} + +/** + * check an object is null or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isNull(value) { + return getType(value) === DataTypes.Null; +} + +/** + * check an object is undefined or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isUndefined(value) { + return getType(value) === DataTypes.Undefined; +} + +/** + * check an object is null or undefined or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isNullOrUndefined(value) { + return isNull(value) || isUndefined(value); +} + +/** + * check an object is a date or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isDate(value) { + return getType(value) === DataTypes.Date; +} + +/** + * check an object is number or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isNumber(value) { + return getType(value) === DataTypes.Number; +} + +/** + * check an object is string or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isString(value) { + return getType(value) === DataTypes.String; +} + +/** + * check an object is boolean or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isBoolean(value) { + return getType(value) === DataTypes.Boolean; +} + +/** + * check an object is an Array or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isArray(value) { + return getType(value) === DataTypes.Array; +} + +/** + * check an object is and Object or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isObject(value) { + return getType(value) === DataTypes.Object; +} + +/** + * check an object is a Function or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isFunction(value) { + return getType(value) === DataTypes.Function; +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + DataTypes, + + // + getType, + getConstructor, + getPrototype, + isNull, + isUndefined, + isNullOrUndefined, + isDate, + isNumber, + isString, + isBoolean, + isArray, + isObject, + isFunction, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/JsModules/x-value.tools.js b/MQLTestWorkspace/BKPS/14030309/JsModules/x-value.tools.js new file mode 100644 index 0000000..81cfcc4 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/JsModules/x-value.tools.js @@ -0,0 +1,1528 @@ +/** + * Value Tools Module ... + * a module for Validate args and values ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Imports ... +const XTypeTools = require('./x-type-detector.tools'); +//#endregion + +// +//#region Actions ... +/** +* validate a value as an argument ... +* +* @param {string} value the value which going to validate ... +* @returns +*/ +function isValidArg(value) { + // + let result = false; + + // + result = value && + value.length > 0; + + // + return result; +} + +/** + * validate a collection of valuea as an arguments ... + * + * @param {string|string[]} values the value collection which going to checked ... + * @returns + */ +function isValidArgs(values) { + // + // Normalize Values ... + const normalValues = toNormalArray(values); + if (!hasChildArray(normalValues)) { + return false; + } + + // + let result = normalValues.every(nv => isValidArg(nv)); + return result; +} + +/** + * converts content to an array object ... + * + * @param {string|string[]} content the content which required to normalized ... + * @returns {string[]} array object ... + */ +function toNormalArray(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + const result = Array.isArray(content) ? + [...content] : + content.includes(',') && + content !== ',' ? + [...content.split(',')] : + [content]; + + // + return result; +} + +/** + * determines value is array and has atleast one child ... + * + * @param {any} value the value which going to checked ... + * @returns {boolean} result of checking ... + */ +function hasChildArray(value) { + // + let result = false; + result = value && + Array.isArray(value) && + value.length > 0; + + // + return result; +} + +/** + * check an string is ends with specified symbol ... + * + * @param {string} symbol specified search symbol ... + * @param {string} value specified search content ... + * @param {boolean} ignoreCase specified search case sensitive or not ... + * @returns + */ +function endsWidth( + symbol = '', + value = '', + ignoreCase = true +) { + // + if (!isValidArg(value)) { + return false; + } + + // + if (!isValidArg(symbol)) { + return true; + } + + // + // TODO: uncomment it if necessary ... + // symbol = symbol.trim(); + + // + let result = false; + const subtractedContent = value.substring(value.length - symbol.length); + result = !!ignoreCase ? + subtractedContent + .toLowerCase() === symbol + .toLowerCase() : + subtractedContent === symbol; + + // + return result; +} + +/** + * surround specified content by provided symbol ... + * + * @param {string} symbol surround string ... + * @param {string} content used content to surrounded by symbol ... + * @returns surrounded content ... + */ +function surroundBy( + symbol = '', + content = '' +) { + // + // Validate Args ... + if (!isValidArg(content)) { + content = ''; + } + + // + if (!isValidArg(symbol)) { + symbol = ''; + } + + // + if (isSurrounded(symbol, content)) { + return content; + } + + // + const result = `${symbol}${content}${symbol}`; + return result; +} + +/** + * convert a parsed sign to clear string ... + * + * @param {string} value a parsed content ... + * @returns clear parsed signs ... + */ +function toStringExpression(value) { + // + let result = ''; + result = value; + + // + if ( + !value || + !isValidArg(value) || + !isSurroundedString(value) + ) { + return result; + } + + // + const startSymbol = value.charAt(0); + const endSymbol = value.charAt(value.length - 1); + + // + if (startSymbol !== endSymbol) { + return result; + } + + // + if ( + startSymbol === "\"" || + startSymbol === "\'" + ) { + result = clearSurround(startSymbol, value); + } + + // + return result; +} + + + +/** + * find and cleare proposed candidates from specified content ... + * + * @param {string|string[]} candidates the proposed string(s) whic going to cleared from content ... + * @param {string} content the destination content which used to find and replace candidates on it ... + * @returns cleared content ... + */ +function clearContent( + candidates, + content +) { + // + // Validate Args ... + if ( + !candidates || + !isValidArg(content) + ) { + return ''; + } + + // + // Normalize candidates ... + const normalCandidates = toNormalArray(candidates) + .filter(c => isValidArg(c)); + if (!hasChildArray(normalCandidates)) { + return content; + } + + // + // define regexp for content ... + const regExpExpression = normalCandidates.join('|'); + const regExp = new RegExp( + regExpExpression, + 'gi' + ); + + // + let result = ''; + result = content.replace(regExp, ''); + + // + return result; +} + +/** + * clear surrounded symbol from content ... + * + * @param {string} symbol specified search symbol ... + * @param {string} content specified content to clear ... + * @returns + */ +function clearSurround( + symbol = '', + content = '' +) { + // + // Validate Args ... + if ( + !isValidArg(content) || + (isValidArg(symbol) && + symbol.length >= content.length - 1) + ) { + return ''; + } + + // + // Validate Surround ... + if (!isSurrounded(symbol, content)) { + return content; + } + + // + if (!isValidArg(symbol)) { + return content; + } + + // + let result = content.substring(symbol.length, content.length - symbol.length); + return result; +} + +/** + * clear object sign ... + * + * @param {string} content + * @returns cleared content ... + */ +function clearObjectSurround(content = '') { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isSurroundedObject(content) + ) { + return content; + } + + // + const endIndex = content.length - ( + endsWidth('}', content) ? + 1 : + endsWidth('},', content) || + endsWidth('};', content) || + endsWidth('}\n', content) ? + 2 : + 0 + ); + + // + const result = content.substring(1, endIndex); + return result; +} + +/** + * clear array sign ... + * + * @param {string} content + * @returns cleared content ... + */ +function clearArraySurround(content = '') { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isSurroundedArray(content) + ) { + return content; + } + + // + const endIndex = content.length - ( + endsWidth(']', content) ? + 1 : + endsWidth('],', content) || + endsWidth('];', content) || + endsWidth(']\n', content) ? + 2 : + 0 + ); + + // + const result = content.substring(1, endIndex); + return result; +} + +/** + * slice a content to individual parts ... + * + * @param {number|number[]} indexes which indexes used to slice ... + * @param {strng} content the content which going to sliced ... + * @returns sliced parts of content ... + */ +function sliceContent(indexes, content) { + // + // Validate Args ... + if ( + !isValidArg(indexes) || + !isValidArg(content) + ) { + return []; + } + + // + // Normalize indexes ... + const normalIndexes = toNormalArray(indexes) + .filter(index => index > -1 && index < content.length); + if (!hasChildArray(normalIndexes)) { + return []; + } + + // + let result = ['']; + result.pop(); + + // + let lastIndex = 0; + for (const index of normalIndexes) { + // + const part = content.substring(lastIndex, index); + if (isValidArg(part)) { + result.push(part.trim()); + } + + // + lastIndex = index + 1; + } + + // + // check remained parts ... + if (lastIndex < content.length) { + // + const part = content.substring(lastIndex); + if (isValidArg(part)) { + result.push(part.trim()); + } + } + + // + return result; +} + + + +/** + * check an string is starts and ends with specified symbol ... + * + * @param {string} symbol specified search symbol ... + * @param {string} content specified search content ... + * @param {boolean} ignoreCase specified search case sensitive or not ... + * @returns + */ +function isSurrounded( + symbol = '', + content = '', + ignoreCase = true +) { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + if (!isValidArg(symbol)) { + return true; + } + + // + symbol = symbol.trim(); + + // + let result = false; + result = (!!ignoreCase ? + content + .toLowerCase() + .startsWith(symbol.toLowerCase()) : + content.startsWith(symbol) + ) && + endsWidth(symbol, content, ignoreCase); + + // + return result; +} + +/** + * determines a content is an string surrounded value or not ... + * + * @param {string} content a content which going to check ... + * @returns + */ +function isSurroundedString(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + let result = false; + result = ( + content.startsWith('\'') && + ( + endsWidth('\'', content) || + endsWidth('\',', content) || + endsWidth('\';', content) || + endsWidth('\'\n', content) + ) || + content.startsWith('\"') && + ( + endsWidth('\"', content) || + endsWidth('\",', content) || + endsWidth('\";', content) || + endsWidth('\"\n', content) + ) || + content.startsWith('`') && + ( + endsWidth('\`', content) || + endsWidth('\`,', content) || + endsWidth('\`;', content) || + endsWidth('\`\n', content) + ) + ); + return result; +} + +/** + * check a content is an array content or not ... + * + * @param {string} content + * @returns + */ +function isSurroundedArray(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + let result = false; + result = content.startsWith('[') && + ( + endsWidth(']', content) || + endsWidth('],', content) || + endsWidth('];', content) || + endsWidth(']\n', content) + ); + return result; +} + +/** + * check a content is an object content or not ... + * + * @param {string} content + * @returns + */ +function isSurroundedObject(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + let result = false; + result = content.startsWith('{') && + ( + endsWidth('}', content) || + endsWidth('},', content) || + endsWidth('};', content) || + endsWidth('}\n', content) + ); + return result; +} + +/** + * check an index model is contains inside anothers or not ... + * + * @param {{ start: number, end: number}} source the source index model to check ... + * @param {...{ start: number, end: number}} dest the collection of index models which going to check ... + * @returns + */ +function isIndexInside(source, ...dest) { + // + let result = false; + + // + // Validate Args ... + if (!source || !dest) { + return result; + } + + // + // Check idx is standard ... + if ( + !source || + !source.end || + !source.start || + source.start > source.end + ) { + return false; + } + + // + // Check types of destinations ... + for (let index of dest) { + // + // Check idx is standard ... + if ( + !index || + !index.end || + !index.start || + index.start > index.end + ) { + return false; + } + } + + // + if (dest.includes(source)) { + dest = dest.filter(d => d !== source); + } + + // + const insideContentIndex = dest.find(dIndex => { + // + const result = source.start >= dIndex.start && + source.start <= dIndex.end && + source.end >= dIndex.start && + source.end <= dIndex.end; + return result; + }); + + // + result = insideContentIndex; + return result; +} + +/** + * check a number exists in + * @param {number} idx the number which going to check ... + * @param {{ start: number, end: number}} index the index model + * @returns + */ +function isInsideIndex(idx = -1, index) { + // + let result = false; + + // + // Validate Args ... + if ( + !index || + !index.hasOwnProperty('end') || + !index.hasOwnProperty('start') + ) { + return result; + } + + // + result = idx > index.start && idx < index.end; + return result; +} + +/** + * determines an object is key/value and type ... + * + * @param {any} content the object which we are going to check ... + * @returns + */ +function isKeyValueType(content) { + // + const result = content && + content.hasOwnProperty('key') && + content.hasOwnProperty('type') && + content.hasOwnProperty('value'); + + // + return result; +} + + + +/** + * find all indexes of token(s) in content ... + * + * @param {string|string[]} tokens the tokens which require to search ... + * @param {string} content the content which using to search ... + * @returns {number[]} all occured indexes ... + */ +function findAllIndexes( + tokens, + content +) { + // + // Validate Args ... + if ( + !isValidArg(tokens) || + !isValidArg(content) + ) { + return []; + } + + // + // normalize tokens ... + const normalTokens = toNormalArray(tokens); + if (!hasChildArray(normalTokens)) { + return []; + } + + // + // Parse contents ... + let match; + const result = []; + const regExp = new RegExp( + normalTokens.join('|'), + 'g' + ); + while ((match = regExp.exec(content)) !== null) { + result.push(match.index); + } + if (!hasChildArray(result)) { + return []; + } + + // + return result; +} + +/** + * find nearest symbol in a content from specified index ... + * + * @param {string|string[]} candidates specifies which symbols to find ... + * @param {string} content te content for seasrch ... + * @param {number} startFromIndex the index of start position ... + * @returns + */ +function findNearest( + candidates, + content = '', + startFromIndex = 0 +) { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isValidArg(candidates) || + !isValidArg(content.trim()) + ) { + return ''; + } + + // + // Normalize Content ... + content = content.trim(); + + // + // Normalize Starts From ... + startFromIndex = startFromIndex < 0 || startFromIndex > content.length - 1 ? 0 : startFromIndex; + + // + // Normalize Symbols ... + const normalCandidates = toNormalArray(candidates); + if (!hasChildArray(normalCandidates)) { + return ''; + } + + // + let nearestIndex = findNearestIndex( + normalCandidates, + content, + startFromIndex + ); + if (nearestIndex < 0) { + return ''; + } + + // + let result = content.substring( + nearestIndex, + nearestIndex + Math.max(...normalCandidates.map(nc => nc.length)) + ).trim(); + return result; +} + +/** + * search candidates in content and find nearest one and return it ... + * + * @param {string|string[]} candidates which candidates required to check ... + * @param {string} content the content which required to search candidates ... + * @param {number} startFromIndex the proposed index to start searching content from on ... + * @returns + */ +function findNearestIndex( + candidates = [''], + content = '', + startFromIndex = 0, + ignoreClosedItems = false +) { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isValidArg(candidates) + ) { + return -1; + } + + // + // Mormalize startFromIndex value ... + startFromIndex = startFromIndex < 0 ? + 0 : + startFromIndex > content.length - 1 ? + content.length - 1 : + startFromIndex; + + // + // Normalize candidates ... + let normalCandidates = toNormalArray(candidates); + + // + if (!!ignoreClosedItems) { + normalCandidates = normalCandidates + .map(c => content.indexOf( + c, + startFromIndex + ) + ).map(c => +c) + .filter(c => +c > -1); + } else { + normalCandidates = findAllIndexesOutOfCloseds(normalCandidates, content) + .filter(c => c >= startFromIndex); + } + if (!hasChildArray(normalCandidates)) { + return -1; + } + + // + let result = -1; + result = Math.min(...normalCandidates); + + // + return result; +} + +/** + * find close index of specific sign in destination content ... + * + * @param {string} openSymbol open of area sign ... + * @param {string} closeSymbol close of area sign ... + * @param {string} content the destination content for parsing ... + * @param {number} startsFrom an start index of content for start parsing ... + * @returns + */ +function findCloseIndex( + openSymbol = '', + closeSymbol = '', + content = '', + startsFrom = -1 +) { + // + // Validate Args ... + if ( + startsFrom < 0 || + !isValidArg(content) || + !isValidArg(openSymbol) || + !isValidArg(closeSymbol) || + openSymbol === closeSymbol || + !content.includes(openSymbol) || + !content.includes(closeSymbol) || + startsFrom > content.length - 1 + ) { + return -1; + } + + // + let result = -1; + + // + let index = startsFrom; + const openSignStack = []; + while (index < content.length) { + // + const openCandidate = content.substring(index, index + openSymbol.length); + const closeCandidate = content.substring(index, index + closeSymbol.length); + + // + if (openCandidate === openSymbol) { + openSignStack.push(index); + } else if (closeCandidate === closeSymbol) { + // + if (openSignStack.length > 0) { + openSignStack.pop(); + } + + // + if (openSignStack.length === 0) { + result = index; + break; + } + } + + // + index++; + } + + // + return result; +} + +/** + * find closed contents of specific sign in destination content ... + * + * @param {string} openSymbol open of area sign ... + * @param {string} closeSymbol close of area sign ... + * @param {string} content the destination content for parsing ... + * @param {number} startsFrom an start index of content for start parsing ... + * @returns + */ +function findClosedContent( + openSymbol = '', + closeSymbol = '', + content = '', + startsFrom = 0, +) { + // + let result = [{ + start: -1, + end: -1, + content: '' + }]; + result.pop(); + + // + // Validate Args ... + if ( + !isValidArg(content) || + !isValidArg(openSymbol) || + !isValidArg(closeSymbol) || + !content.includes(openSymbol) || + !content.includes(closeSymbol) || + openSymbol.length >= content.length || + closeSymbol.length >= content.length + ) { + return result; + } + + // + // Normalize Start From ... + startsFrom = startsFrom < 0 || startsFrom >= content.length ? 0 : startsFrom; + + // + let canContinue = true; + while (!!canContinue) { + // + let openSymbolIndex = content.indexOf(openSymbol, startsFrom); + if (openSymbolIndex < 0) { + // + canContinue = false; + continue; + } + + // + let closeSymbolIndex = findCloseIndex( + openSymbol, + closeSymbol, + content, + openSymbolIndex + ); + if (closeSymbolIndex < 0) { + // + canContinue = false; + continue; + } + if (content.charAt(closeSymbolIndex) !== closeSymbol) { + closeSymbolIndex++; + } + + // + // Prevent ${} string interpolations ... + if ( + openSymbol === '{' && + openSymbolIndex - 1 >= 0 + ) { + // + const prevChar = content.charAt(openSymbolIndex - 1); + if (prevChar === '$') { + continue; + } + } + + // + const item = content + .substring(openSymbolIndex, closeSymbolIndex + 1) + .trim(); + startsFrom = closeSymbolIndex + 1; + result.push({ + start: openSymbolIndex, + end: closeSymbolIndex, + content: item + }); + } + + // + if (!hasChildArray(result)) { + return result; + } + + // + return result; +} + +/** + * extract a collection of closed contents exists in a content ... + * + * @param symbols a collection of open and close contents ... + * @param {string} content a content for searching inside it ... + * @returns a collection of closed content ... + */ +function findClosedContents( + symbols = [ + { + openSymbol: '', + closeSymbol: '' + } + ], + content = '' +) { + // + let result = [{ + start: -1, + end: -1, + content: '' + }]; + result.pop(); + + // + if ( + !isValidArg(content) || + !hasChildArray(symbols) + ) { + return []; + } + + // + symbols.forEach(symbol => { + // + const closedContent = findClosedContent( + symbol.openSymbol, + symbol.closeSymbol, + content + ); + + // + if (hasChildArray(closedContent)) { + result.push( + ...closedContent + ); + } + }); + + // + return result; +} + +/** + * find all string content closed items ... + * + * @param {string} content a content which going to search ... + * @returns a collection of index descriptors ... + */ +function findClosedStrings(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + // there are 3 types of strings ... + // ' " and ` + + // + const token1 = '\''; + const token1Stack = [0]; + token1Stack.pop(); + + // + const token2 = '"'; + const token2Stack = [0]; + token2Stack.pop(); + + // + const token3 = '`'; + const token3Stack = [0]; + token3Stack.pop(); + + // + const result = [ + { + start: -1, + end: -1, + content: '' + } + ]; + result.pop(); + + // + for (let i = 0; i < content.length; i++) { + // + const currentChart = content.charAt(i); + + // + //#region Token 1 ... + if (currentChart === token1) { + // + if (!hasChildArray(token1Stack)) { + token1Stack.push(i); + } else { + // + const start = token1Stack.pop(); + const end = i + 1; + const pContent = content.substring(start, end); + result.push({ + start, + end, + content: pContent + }); + } + } + //#endregion + + // + //#region Token 2 ... + if (currentChart === token2) { + // + if (!hasChildArray(token2Stack)) { + token2Stack.push(i); + } else { + // + const start = token2Stack.pop(); + const end = i + 1; + const pContent = content.substring(start, end); + result.push({ + start, + end, + content: pContent + }); + } + } + //#endregion + + // + //#region Token 3 ... + if (currentChart === token3) { + // + if (!hasChildArray(token3Stack)) { + token3Stack.push(i); + } else { + // + const start = token3Stack.pop(); + const end = i + 1; + const pContent = content.substring(start, end); + result.push({ + start, + end, + content: pContent + }); + } + } + //#endregion + } + + // + return result; +} + +/** + * find container indexes from within indexes ... + * + * @param {...{start: number, end: number}} index the collection of indexes to find beiggers inside ... + * @returns + */ +function findContainerIndexes(...index) { + // + let result = [ + { + start: -1, + end: -1, + content: '' + } + ]; + result.pop(); + + // + let concatedIndexes = []; + for (let idx of index) { + // + // Index Childs ... + for (let iix of idx) { + // + // Check idx is standard ... + if ( + !iix || + !iix.end || + !iix.start || + iix.start > iix.end + ) { + continue; + } + + // + // Check index inside another index ... + concatedIndexes.push(iix); + } + } + + // + if (!hasChildArray(concatedIndexes)) { + return result; + } + + // + for (let ccIdx of concatedIndexes) { + // + const isInside = isIndexInside(ccIdx, ...concatedIndexes); + if (isInside) { + continue; + } + + // + if (hasChildArray(result)) { + // + const isInsideResult = isIndexInside(ccIdx, ...result); + if (isInsideResult) { + continue; + } + } + + // + result.push(ccIdx); + } + + // + return result; +} + +/** + * find all tokens indexes inside a content which they are not inside closed items ... + * + * @param {string|string[]} tokens the tokens which require to search ... + * @param {string} content the content which using to search ... + * @returns + */ +function findAllIndexesOutOfCloseds1( + tokens, + content, +) { + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + // Extract token Indexes ... + const tokensIndexes = findAllIndexes(tokens, content); + if (!hasChildArray(tokensIndexes)) { + return []; + } + + // + // Extract Closed Objects Indexes ... + const closedArrays = findClosedContent('[', ']', content); + const closedObjects = findClosedContent('{', '}', content); + const closedStrings = findClosedStrings(content); + if ( + !hasChildArray(closedObjects) && + !hasChildArray(closedArrays) && + !hasChildArray(closedStrings) + ) { + return tokensIndexes; + } + + // + // find bigger sloded ... + let containerClosedItems = findContainerIndexes( + closedArrays, + closedObjects, + closedStrings + ).filter(i => !isSurroundedString(i.content)); + + // + let result = [-1]; + result.pop(); + + // + for (let tIdx of tokensIndexes) { + // + let canAdd = true; + for (let ccIndex of containerClosedItems) { + // + canAdd = isInsideIndex(tIdx, ccIndex); + if (canAdd) { + break; + } + } + + // + if (!canAdd) { + result.push(tIdx); + } + } + + // + return result; +} + +/** + * find all tokens indexes inside a content which they are not inside closed items ... + * + * @param {string|string[]} tokens the tokens which require to search ... + * @param {string} content the content which using to search ... + * @returns + */ +function findAllIndexesOutOfCloseds( + tokens, + content, +) { + // + // Define Result ... + let result = [-1]; + result.pop(); + + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + // Normalize Tokens ... + const normalizeTokens = toNormalArray(tokens); + if (!hasChildArray(normalizeTokens)) { + return result; + } + + // + // Extract Closed Objects Indexes ... + let openSymbols = [ + '{', + '[', + '\'', + '"', + '`' + ]; + let closeSymbols = [ + '}', + ']', + '\'', + '"', + '`' + ]; + let openStack = []; + let lastOpenSymbol = ''; + let lastClosedIndex = -1; + for (let i = 0; i < content.length; i++) { + // + const prevChar = content.charAt(i - 1) || ''; + const char = content.charAt(i); + const nextChar = content.charAt(i + 1) || ''; + + // + const isToken = normalizeTokens.includes(char); + const isOpenSymbol = openSymbols.includes(char); + const isCloseSymbol = closeSymbols.includes(char); + + // + if (isOpenSymbol && lastOpenSymbol !== char) { + openStack.push(i); + lastOpenSymbol = char === '\'' || char === '"' || char === '`' ? char : lastOpenSymbol; + } else if (isCloseSymbol) { + // + lastOpenSymbol = char === '\'' || char === '"' || char === '`' ? '' : lastOpenSymbol; + let lastPop = openStack.pop(); + if (openStack.length === 0) { + lastClosedIndex = lastPop; + } + } else if (isToken) { + if ( + i > lastClosedIndex && + openStack.length === 0 + ) { + result.push(i); + } + } + } + + // + return result; +} +//#endregion + +// +//#region Validator Actions ... +/** + * check specified value is Valid URL Address or not ... + * + * @param {string} value specified string which required to check + * @returns {boolean} + */ +function isValidURL(value = "") { + // + if (!isValidArg(value)) { + return false; + } + + const pattern = new RegExp( + '^([a-zA-Z]+:\\/\\/)?' + // protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name + '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR IP (v4) address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path + '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string + '(\\#[-a-z\\d_]*)?$', // fragment locator + 'i' + ); + + // + const result = pattern.test(value); + return result; +} + +/** + * check specified value is Valid URL Address or not ... + * + * @param {string} value specified string which required to check + */ +function isValidEmail(value = "") { + // + if (!isValidArg(value)) { + return false; + } + + // + const pattern = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/gim; + + // + const result = pattern.test(value); + return result; +} +//#endregion + +// +//#region Normallizers ... +/** + * normallize an string ... + * + * @param {string} value specified value ... + * @returns {string} + */ +function toNormalString(value = "") { + // + if (!XTypeTools.isString(value)) { + value = ""; + } + + // + const result = value + .trim() + .toLowerCase(); + + // + return result; +} +//#endregion + +// +//#region Beautifiers ... +/** + * converts an object to string based on json and beautify result ... + * + * @param {any} object + * @returns {string} + */ +function beautifyJSON(object = undefined) { + // + // TODO: Complete this ... + let result = ""; + + // + // validate object ... + if (object === undefined) { + return result; + } + + // + // Convert result ... + result = JSON.stringify( + object, + null, + 4 + ); + + // + return result; +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + endsWidth, + surroundBy, + isValidArg, + isValidArgs, + toNormalArray, + hasChildArray, + toStringExpression, + + // + sliceContent, + clearContent, + clearSurround, + clearArraySurround, + clearObjectSurround, + + // + isSurrounded, + isIndexInside, + isInsideIndex, + isKeyValueType, + isSurroundedArray, + isSurroundedString, + isSurroundedObject, + + // + findNearest, + findAllIndexes, + findCloseIndex, + findNearestIndex, + findClosedContent, + findClosedStrings, + findClosedContents, + findAllIndexesOutOfCloseds, + + // + // Validator Actions ... + isValidURL, + isValidEmail, + + // + // Normallizers ... + toNormalString, + + // + beautifyJSON, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.common.lib.mq5 b/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..e2bd85a --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,7165 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommonLib +// Description: provide all commonly used functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xmd5.class.mq5" + +// +// Models ... + +// +// Specified Price Type ... +enum ENUM_X_PRICE +{ + X_PRICE_HIGH, + X_PRICE_OPEN, + X_PRICE_CLOSE, + X_PRICE_LOW +}; + +// +// Swing Types Enum ... +enum ENUM_X_SWING_TYPE +{ + X_NO_SWING = 0, + X_SWING_HIGH = 1, + X_SWING_LOW = -1, +}; + +// +// XPERIOD Calculation Method ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, // Nothing + X_PERIOD_AUTO, // Auto Select + X_PERIOD_MANUALLY // Manually +}; + +// +// Available Market Cycles ... +enum ENUM_X_MARKET_CYCLES +{ + // + X_MARKET_CYCLE_UNKNOWN, // Unknown Cycle + X_MARKET_CYCLE_SHORT, // Short Cycle + X_MARKET_CYCLE_MEDIUM, // Medium Cycle + X_MARKET_CYCLE_LONG, // Long Cycle + X_MARKET_CYCLE_HIND, // Hind Cycle +}; + +// +// Structs ... + +// +// Model a Bar Remains Time ... +struct XBarRemainsTime +{ + // + int days; + int hours; + int minutes; + int seconds; + + // + // Constructor ... + XBarRemainsTime() + { + Clean(); + } + + // + // Always Calculate Current 0 Bar Timing ... + bool Init( + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period + ) + { + // + bool result = false; + + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + int minuteSecoonds = 60; + int hourSeconds = minuteSecoonds * 60; + int daySeconds = 24 * hourSeconds; + + // + int periodSeconds = PeriodSeconds( + mPeriod); + datetime startTime = GetBarTime( + mSymbol, + mPeriod, + 0 + // + ); + + // + int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); + + // + int mWorkingSecondsDiff = secondsDiff; + if (mWorkingSecondsDiff > daySeconds) + { + // + days = mWorkingSecondsDiff / daySeconds; + mWorkingSecondsDiff -= days * daySeconds; + } + if (mWorkingSecondsDiff > hourSeconds) + { + // + hours = mWorkingSecondsDiff / hourSeconds; + mWorkingSecondsDiff -= hours * hourSeconds; + } + if (mWorkingSecondsDiff > minuteSecoonds) + { + // + minutes = mWorkingSecondsDiff / minuteSecoonds; + mWorkingSecondsDiff -= minutes * minuteSecoonds; + } + seconds = mWorkingSecondsDiff; + + // + result = true; + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + days = 0; + hours = 0; + minutes = 0; + seconds = 0; + } + + // + // To String Representation ... + string ToString( + string dayId = "d", + string hourId = "h", + string minuteId = "m", + string secondId = "s", + string idSeparator = ": ", + string separator = ", ", + bool ignoreZeroValues = true + // + ) + { + // + string result = ""; + + // + // Days ... + if (!ignoreZeroValues || days > 0) + { + result += dayId + idSeparator + (string)days + separator; + } + + // + // Hours ... + if (!ignoreZeroValues || hours > 0) + { + // + string strHour = ToString(hours); + if (StringLen(strHour) == 1) + { + strHour = "0" + strHour; + } + + // + result += hourId + idSeparator + strHour + separator; + } + + // + // Minutes ... + if (!ignoreZeroValues || minutes > 0) + { + // + string strMinute = ToString(minutes); + if (StringLen(strMinute) == 1) + { + strMinute = "0" + strMinute; + } + + // + result += minuteId + idSeparator + strMinute + separator; + } + + // + // Seconds ... + if (!ignoreZeroValues || seconds > 0) + { + // + string strSec = ToString(seconds); + if (StringLen(strSec) == 1) + { + strSec = "0" + strSec; + } + + // + result += secondId + idSeparator + strSec; + } + + // + return result; + } +}; + +// +// Describe an Specific Candle ... +struct XOHCL +{ + // + // Props ... + + // + double high; + double open; + double close; + double low; + + // + string symbol; + datetime time; + ENUM_TIMEFRAMES period; + + // + // Constructor ... + XOHCL() + { + Clean(); + } + + // + // Init a Bar ... + // Using Bar Index ... + bool Init( + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period + int barIndex = 0 // Bar Index + ) + { + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + symbol = mSymbol; + period = mPeriod; + + // + time = iTime( + mSymbol, + mPeriod, + barIndex + // + ); + + // + open = iOpen( + mSymbol, + mPeriod, + barIndex + // + ); + + // + close = iClose( + mSymbol, + mPeriod, + barIndex + // + ); + + // + high = iHigh( + mSymbol, + mPeriod, + barIndex); + + // + low = iLow( + mSymbol, + mPeriod, + barIndex + // + ); + + // + bool result = IsValid(); + + // + return result; + } + + // + // Init a Bar ... + // Using Bar Time ... + bool Init( + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period + datetime mTime = NULL // Bar Time + ) + { + // + mTime = NormalizeTime(mTime); + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false // + ); + + // + bool result = Init( + mSymbol, + mPeriod, + barIndex + // + ); + + // + return result; + } + + // + bool Init( + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period + double mOpen = 0, // Open + double mHigh = 0, // High + double mClose = 0, // Close + double mLow = 0, // Low + int barIndex = 0 // Bar Index + ) + { + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + symbol = mSymbol; + period = mPeriod; + + // + time = iTime( + mSymbol, + mPeriod, + barIndex + // + ); + + // + open = mOpen; + high = mHigh; + close = mClose; + low = mLow; + + // + return IsValid(); + } + + // + bool Init( + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period + double mOpen = 0, // Open + double mHigh = 0, // High + double mClose = 0, // Close + double mLow = 0, // Low + datetime mTime = NULL // Bar Time + ) + { + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + symbol = mSymbol; + period = mPeriod; + + // + int barIndex = iBarShift( + symbol, + period, + mTime); + + // + time = iTime( + mSymbol, + mPeriod, + barIndex + // + ); + + // + open = mOpen; + high = mHigh; + close = mClose; + low = mLow; + + // + return IsValid(); + } + + // + // Tools ... + + // + void Clean() + { + // + high = 0; + open = 0; + close = 0; + low = 0; + + // + time = NULL; + symbol = NULL; + period = NULL; + } + + // + // Validate Bar ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + high > 0 && + open > 0 && + close > 0 && + low > 0 + // + ; + + // + return result; + } + + // + // Calculate X_PRICE Specified Type ... + double GetPrice(ENUM_X_PRICE mPType) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + switch (mPType) + { + // + case X_PRICE_OPEN: + result = open; + break; + // + case X_PRICE_HIGH: + result = high; + break; + // + case X_PRICE_CLOSE: + result = close; + break; + // + case X_PRICE_LOW: + result = low; + break; + } + + // + return result; + } + + // + // Retrieve Price base On Series Mode ... + double GetPrice(ENUM_SERIESMODE mMode) + { + // + ENUM_X_PRICE mXMode = ToPrice(mMode); + + // + return GetPrice(mXMode); + } + + // + // Calculate Applied Price ... + double GetPrice( + ENUM_APPLIED_PRICE mAppliedTo // Select Application Method + ) + { + // + double result = 0; + + // + // Calculate Applied Price ... + switch (mAppliedTo) + { + // + case PRICE_CLOSE: + result = close; + break; + + // + case PRICE_OPEN: + result = open; + break; + + // + case PRICE_HIGH: + result = high; + break; + + // + case PRICE_LOW: + result = low; + break; + + // + case PRICE_MEDIAN: + result = (high + low) / 2; + break; + + // + case PRICE_TYPICAL: + result = (high + low + close) / 3; + break; + + // + case PRICE_WEIGHTED: + result = (high + low + close + close) / 4; + break; + } + + // + return result; + } + + // + // Calculate Bar Mid Line ... + double GetMid() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = (high + low) / 2; + + // + return result; + } + + // + // Calculate up Price ... + double GetUp() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = MathMax(open, close); + + // + return result; + } + + // + // Calculate Down Price ... + double GetDown() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = MathMin(open, close); + + // + return result; + } + + // + // Calculate Bar Body ... + double GetBody() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetUp() - GetDown(); + + // + return result; + } + + // + // Calculate Bar Range ... + double GetRange() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = high - low; + + // + return result; + } + + // + // Calculate Bar Shadows ... + double GetShadows() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetRange() - GetBody(); + + // + return result; + } + + // + // Calculate Bar High Shadow ... + double GetHighShadow() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = + // + high - GetUp() + // + ; + + // + return result; + } + + // + // Calculate Bar Low Shadow ... + double GetLowShadow() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = + // + GetDown() - low; + // + ; + + // + return result; + } + + // + // Check Bar is Bullish ... + bool IsBullish() + { + // + bool result = false; + + // + if (!IsValid()) + { + return result; + } + + // + result = open < close; + + // + return result; + } + + // + // Check Bar is Bearish ... + bool IsBearish() + { + // + bool result = false; + + // + if (!IsValid()) + { + return result; + } + + // + result = open > close; + + // + return result; + } + + // + // Find Next Bar Time ... + datetime NextAt() + { + // + datetime result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + int prSeconds = PeriodSeconds(period); + + // + result = time + prSeconds; + + // + return result; + } + + // + // Find Prev Bar Time ... + datetime BeforeOn() + { + // + datetime result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + int prSeconds = PeriodSeconds(period); + + // + result = time - prSeconds; + + // + return result; + } + + // + // Find Current Bar Index on Chart ... + int Index() + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + result = iBarShift( + symbol, + period, + time + // + ); + + // + return result; + } + + // + bool GetPreviousBar(XOHCL &bar) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + int idx = Index(); + + // + result = bar.Init( + this.symbol, + this.period, + idx + 1 // + ); + + // + return result; + } + + // + // Check Bar has Strong Body or Not ... + bool HasStrongBody() + { + // + bool result = false; + + // + if (!IsValid()) + { + return result; + } + + // + double body = GetBody(); + double shadow = GetShadows(); + + // + result = body > shadow * 1.5; + + // + return result; + } + + // + // Bar Must Open Below Prce + // and Close Above it ... + bool IsBreakUp( + double price // a Price to Check Breake + ) + { + // + bool result = false; + + // + result = HasStrongBody(); + if (!result || price <= 0) + { + return result; + } + + // + // Select required Prices ... + + // + result = + // + close > price && + open < price; + + // + return result; + } + + // + // Bar Must Open Above Prce + // and Close Below it ... + bool IsBreakDown( + double price // a Price to Check Breake + ) + { + // + bool result = false; + + // + result = HasStrongBody(); + if (!result || price <= 0) + { + return result; + } + + // + // Select required Prices ... + + // + result = + // + open > price && + close < price; + + // + return result; + } + + // + bool IsBreakOut( + double price, // a Price to Check Breake + bool useHighLow = true // if true using High and Low price for Breakeouts, if not use Open Close + ) + { + // + bool result = false; + + // + result = HasStrongBody(); + if (!result || price <= 0) + { + return result; + } + + // + // Select required Prices ... + + // + double selectedUp = + useHighLow + ? high + : GetUp(); + double selectedDown = + useHighLow + ? low + : GetDown(); + + // + result = + // + selectedUp > price && + selectedDown < price; + + // + return result; + } + + // + // Check Bar is Inside Previus Bar ... + bool IsInsideBar( + double threshold = 5 // Points Distance between Up and Down + ) + { + // + bool result = false; + + // + if (threshold < 0) + { + threshold = 0; + } + + // + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + double offset = PointToPrice(threshold, this.symbol); + + // + result = + // + pBar.high > this.high && + pBar.low < this.low && + MathAbs(pBar.low - this.low) > offset && + MathAbs(pBar.high - this.high) > offset + // + ; + + // + return result; + } + + // + // Check Bar has Strongest Body in a Range ... + bool HasStrongestBody( + int loopback = 3 // loopback candles to compare it ... + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double body = GetBody(); + XOHCL prev = this; + for (int i = 0; i < loopback; i++) + { + // + bool isValid = prev.GetPreviousBar(prev); + if (!isValid) + { + // + result = false; + break; + } + + // + result = + // + result && + body > prev.GetBody() + // + ; + if (!result) + { + break; + } + } + + // + return result; + } + + // + // Check Bar has Weakest Body in a Range ... + bool HasWeakestBody( + int loopback = 3 // loopback candles to compare it ... + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double body = GetBody(); + XOHCL prev = this; + for (int i = 0; i < loopback; i++) + { + // + bool isValid = prev.GetPreviousBar(prev); + if (!isValid) + { + // + result = false; + break; + } + + // + result = + // + result && + body < prev.GetBody() + // + ; + if (!result) + { + break; + } + } + + // + return result; + } + + // + // Determines Swings based On this Bar ... + // Calculates Based on atleast 3 Bars Prev ... + ENUM_X_SWING_TYPE GetSwingType() + { + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Find Current Index of Bar ... + int barIndex = Index(); + if (barIndex <= -1) + { + return result; + } + + // + // First we have to Retrieve atleast 3 Bars before this bar ... + XOHCL bars[]; + int barsCount = GetBars( + bars, + symbol, + period, + barIndex + 1, + 3 + // + ); + if (barsCount < 3) + { + return result; + } + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = bars[2].HasStrongBody(); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + bars[2].low < bars[1].low && + bars[1].low < bars[0].low && + bars[2].low < bars[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + bars[2].high > bars[1].high && + bars[1].high > bars[0].high && + bars[2].high > bars[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; + } + + // + // Find Swings (Highs nd Lows) ... + int FindSwing( + ENUM_X_SWING_TYPE swing, // Swing Based On Price mode ... + int mLength // Loopback ... + ) + { + // + int result = -1; + + // + if (!IsValid() || + !IsValid(swing)) + { + return result; + } + + // + int current = Index(); + int founded = FindNextSwing( + swing, + (mLength * 2) + 1, + current - mLength + // + ); + + // + while (founded != current) + { + // + current = FindNextSwing( + swing, + mLength, + current + 1 + // + ); + + // + founded = FindNextSwing( + swing, + (mLength * 2) + 1, + current - mLength + // + ); + } + + // + result = current; + + // + return result; + } + + // + // Find Next Swing ... + int FindNextSwing( + ENUM_X_SWING_TYPE swing, // Swing Based On Price mode ... + int from, // from Bar Index + int mLength // Loopback ... + ) + { + // + int result = -1; + + // + if (!IsValid() || + !IsValid(swing)) + { + return result; + } + + // + if (from < 0) + { + mLength += from; + from = 0; + } + + // + ENUM_SERIESMODE mMode = swing == X_SWING_HIGH + ? MODE_HIGH + : MODE_LOW; + + // + result = swing == X_SWING_HIGH + ? iHighest( + symbol, + period, + mMode, + mLength, + from) + : iLowest( + symbol, + period, + mMode, + mLength, + from); + + // + return result; + } + + // + // Find Lowest Bar Index ... + int FindHighestIndex( + int mLength, // Loopback ... + ENUM_SERIESMODE mMode // Calculation mode + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (mLength < 2) + { + mLength = 2; + } + + // + result = iHighest( + symbol, + period, + mMode, + mLength, + Index()); + + // + return result; + } + + // + // Find Lowest ... + double FindHighest( + int mLength, // Loopback ... + ENUM_SERIESMODE mMode // Calculation mode + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + int idx = FindHighestIndex( + mLength, + mMode); + if (idx <= -1) + { + return result; + } + + // + XOHCL iH; + result = iH.Init( + symbol, + period, + idx + // + ); + if (!result) + { + return result; + } + + // + result = iH.GetPrice(mMode); + + // + return result; + } + + // + // Find Lowest Bar Index ... + int FindLowestIndex( + int mLength, // Loopback ... + ENUM_SERIESMODE mMode // Calculation mode + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (mLength < 2) + { + mLength = 2; + } + + // + result = iLowest( + symbol, + period, + mMode, + mLength, + Index()); + + // + return result; + } + + // + // Find Lowest ... + double FindLowest( + int mLength, // Loopback ... + ENUM_SERIESMODE mMode // Calculation mode + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + int idx = FindLowestIndex( + mLength, + mMode); + if (idx <= -1) + { + return result; + } + + // + XOHCL iL; + result = iL.Init( + symbol, + period, + idx + // + ); + if (!result) + { + return result; + } + + // + result = iL.GetPrice(mMode); + + // + return result; + } + + // + // Candlestic Tools ... + + // + bool IsDoji() { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) { + return result; + } + + // + result = open == close; + + // + return result; + } + + // + // Convert to String Representation ... + string ToString() + { + // + string result = ""; + + // + result = GetTypeName(this) + + "(O(" + ToString(open) + "),H(" + ToString(high) + "),C(" + ToString(close) + "),L(" + ToString(low) + "))"; + + // + return result; + } +}; + +// +// Model Support and Resistance +// for Specific Bar ... +struct XOHCLSupRes +{ + // + // Props ... + + // + /// Resistances ... + double res[]; + + // + // Supports ... + double sup[]; + + // + // Constructor ... + XOHCLSupRes() + { + Clean(); + } + + // + // Init ... + bool Init( + double price, // Price ... + const double &pivots[], // Provided Pivot Points ... + int count = 3, // Number of Requireds ... + double step = 0 // Distance between each item with it's Last Side ... + ) + { + // + bool result = false; + + // + Clean(); + + // + if (price <= 0) + { + return result; + } + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + double lastR = 0; + double tmpR[]; + + // + double lastS = 0; + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > price) + { + // + bool canAdd = + step <= 0 + ? true + : lastR == 0 || MathAbs(iFlat - lastR) >= step; + if (canAdd) + { + // + Add( + iFlat, + tmpR); + + // + lastR = iFlat; + } + } + else if (iFlat < price) + { + // + bool canAdd = + step <= 0 + ? true + : lastS == 0 || MathAbs(iFlat - lastS) >= step; + if (canAdd) + { + // + Add( + iFlat, + tmpS); + + // + lastS = iFlat; + } + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + res, + tmpR); + } + else + { + // + ArrayCopy( + res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + sup, + tmpS); + } + else + { + // + ArrayCopy( + sup, + tmpS, + 0, + 0, + count); + } + } + + // + result = IsValid(); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + Clean(sup); + Clean(res); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + CountSupports() > 0 || + CountResistances() > 0 + // + ; + + // + return result; + } + + // + int CountSupports() + { + return ArraySize(sup); + } + + // + int CountResistances() + { + return ArraySize(res); + } +}; + +// +// Tracking Times ... +struct XTimeTracker +{ + // + // Props ... + int xMonth; + int xDayOfWeek; + int xForWeekDay; + int xDay; + int xHour; + + // + // Constructor ... + XTimeTracker() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + xDay = -1; + xHour = -1; + xMonth = -1; + xDayOfWeek = -1; + xForWeekDay = -1; + } + + // + // Detecting New Houre ... + bool IsNewHour() + { + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.hour != xHour; + if (result) + { + xHour = timeStruct.hour; + } + + // + return result; + } + + // + // Detecting New Day ... + bool IsNewDay() + { + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.day_of_year != xDay; + if (result) + { + xDay = timeStruct.day_of_year; + } + + // + return result; + } + + // + // Detecting New Week ... + bool IsNewWeek() + { + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Week ... + // Since Week Starts From Monday in Forex World ... + // we Calculate Start of Week by 1-Monday ... + result = + xDayOfWeek == -1 && + xForWeekDay == -1 + ? true + : timeStruct.day_of_week == 1 && + timeStruct.day_of_year > xForWeekDay; + + // + xForWeekDay = timeStruct.day_of_year; + xDayOfWeek = timeStruct.day_of_week; + + // + return result; + } + + // + // Detecting End Of Week ... + bool IsWeekEnd() + { + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check WeekEnd ... + // Since Week Starts From Monday in Forex World ... + // we Calculate End of Week by 5-Friday ... + result = + xDayOfWeek != -1 && + timeStruct.day_of_week == 5 && + timeStruct.hour == 23 && + timeStruct.min == 59 && + timeStruct.sec == 59; + + // + return result; + } + + // + // Detecting New Month ... + bool IsNewMonth() + { + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.mon != xMonth; + if (result) + { + xMonth = timeStruct.mon; + } + + // + return result; + } +}; + +// +// Tracking Bars on Specified Environment ... +struct XBarTracker +{ + // + string symbol; // Tracking Symbol + ENUM_TIMEFRAMES period; // Tracking Time Frame + + // + int lastTrackedBar; // Last Tracked Bar ... + + // + // Constructor ... + XBarTracker() + { + Clean(); + } + + // + // Initializer ... + bool Init( + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period + ) + { + // + bool result = false; + + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + this.symbol = mSymbol; + this.period = mPeriod; + + // + this.lastTrackedBar = 0; + + // + result = true; + + // + return result; + } + + // + // Retrieve all Bars ... + int CountBars() + { + // + return Bars( + symbol, + period + // + ); + } + + // + // Check if it's New Bar ... + bool IsNewBar() + { + // + bool result = false; + + // + int currentBars = CountBars(); + + // + result = currentBars > lastTrackedBar; + if (result) + { + lastTrackedBar = currentBars; + } + + // + return result; + } + + // + // Tools ... + void Clean() + { + // + symbol = NormalizeSymbol(NULL); + period = NormalizePeriod(NULL); + } +}; + +// +// Track Value Changes ... +template +struct XValueTracker +{ + // + // Definitions ... + + // + // Model a Value Change ... + struct XValueChange + { + // + // Props ... + datetime at; // Change Time + T from; // Before Change Value + T to; // After Change Value + + // + // Constructor ... + XValueChange() + { + Clean(); + } + + // + // Cleanup ... + void Clean() + { + // + at = NULL; + from = NULL; + to = NULL; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValid(at); + if (!result) + { + return result; + } + + // + result = NotEmpty(from) && + NotEmpty(to); + + // + return result; + } + }; + + // + // Props ... + XValueChange changes[]; // Hold Changes + + // + // Constructor ... + XValueTracker() + { + Clean(); + } + + // + // Track a Change Happens Or Not ... + bool Track( + const T &source[] // Data Source for Track Changes + ) + { + // + bool result = false; + + // + if (ArraySize(source) <= 1) + { + return result; + } + + // + datetime time = TimeCurrent(); + + // + double from = source[1]; + double to = source[0]; + + // + result = to != from; + if (result) + { + return result; + } + + // + XValueChange lastChange; + bool hasLastChange = + GetLastItem( + lastChange, + changes + // + ); + result = + !hasLastChange + ? true + : lastChange.at < time && + lastChange.to != to && + lastChange.from != from; + if (!result) + { + return result; + } + + // + lastChange.Clean(); + + // + lastChange.to = to; + lastChange.at = time; + lastChange.from = from; + + // + AddRef( + lastChange, + changes + // + ); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + Clean(changes); + } +}; + +// +// Model a Market Cycle ... +struct XMarketCycle +{ + // + // Props ... + + // + string prefix; // Prefix Trag ... + + // + string symbol; // Market Symbol ... + + // + ENUM_TIMEFRAMES period; // Period of Cycle ... + ENUM_X_PERIOD_METHOD method; // Period Selection Method ... + ENUM_X_MARKET_CYCLES cycle; // Cycles of MArket ... + + // + int length; // Number Of Candles per Current Time Frame ... + ENUM_TIMEFRAMES hostPeriod; // Current Time Frame ... + + // + datetime lastStart; // Last Candle Bar Time ... + + // + XBarTracker barTracker; // Bar Tracker ... + XBarRemainsTime remains; // Current Bar Remains Model ... + + // + // Constructor ... + XMarketCycle() + { + Clean(); + } + + // + // Init Cycle ... + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + string mPrefix = "" // Prefix + ) + { + // + bool result = false; + + // + mSymbol = NormalizeSymbol(mSymbol); + mHostPeriod = NormalizePeriod(mHostPeriod); + + // + result = IsValid(mCycle); + if (!result) + { + return result; + } + + // + this.cycle = mCycle; + + // + // Set Automatically Prefix ... + if (StringLen(mPrefix) == 0) + { + this.prefix = ToString(cycle); + } + + // + result = IsValid( + method, + period // + ); + if (!result) + { + return result; + } + + // + this.symbol = mSymbol; + this.hostPeriod = mHostPeriod; + + // + // Find Cycle Period ... + if (method == X_PERIOD_AUTO) + { + // + // Select Period ... + this.period = GetCyclePeriod( + this.cycle, + this.hostPeriod); + } + + // + // Set Prefix if Provided ... + if (StringLen(mPrefix) > 0) + { + this.prefix = mPrefix; + } + + // + // Calculate Required Info ... + + // + // Length ... + this.length = PeriodSeconds(this.period) / PeriodSeconds(this.hostPeriod); + + // + // Update Additional Data ... + result = this.Update(0); + + // + return result; + } + + // + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + ENUM_X_PERIOD_METHOD mMethod, // Period Selection Method + ENUM_TIMEFRAMES mPeriod, // Provided Period + string mPrefix = "" // Prefix + ) + { + // + this.period = mPeriod; + this.method = mMethod; + + // + return Init( + mSymbol, + mHostPeriod, + mCycle, + mPrefix + // + ); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + length = 0; + lastStart = 0; + + // + cycle = NULL; + prefix = NULL; + symbol = NULL; + period = NULL; + method = NULL; + hostPeriod = NULL; + + // + remains.Clean(); + barTracker.Clean(); + } + + // + // Check Structure Valid ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValid( + method, + period); + if (!result) + { + return result; + } + + // + result = + // + length > 0 && + symbol != NULL && + period != NULL && + method != NULL && + hostPeriod != NULL && + method != X_PERIOD_NOTHING + // + ; + + // + return result; + } + + // + // Update Market Cycle Additional Info ... + bool Update(int hostBarIndex) + { + // + bool result = false; + + // + result = this.IsValid(); + if (!result) + { + return result; + } + + // + // Init Remains ... + result = remains.Init( + this.symbol, + this.period); + if (!result) + { + return result; + } + + // + // Init Bar Tracker ... + result = barTracker.Init( + this.symbol, + this.period); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Count Bars ... + int CountBars() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = barTracker.CountBars(); + + // + return result; + } + + // + // Check New Bar ... + bool IsNewBar() + { + // + bool result = false; + + // + if (!IsValid()) + { + return result; + } + + // + result = barTracker.IsNewBar(); + + // + return result; + } + + // + // Retrieve Current Bar Index based on Host Period bar Index ... + int GetBarIndex(int barIndex) + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + if (barIndex < 0) + { + return result; + } + + // + int totalBars = CountBars(); + if (barIndex >= totalBars) + { + // + result = totalBars - 1; + return result; + } + + // + datetime hostBarTime = iTime( + this.symbol, + this.hostPeriod, + barIndex + // + ); + + // + result = iBarShift( + this.symbol, + this.period, + hostBarTime + // + ); + + // + return result; + } + + // + // Retrieve Current Cycles Specific Bar ... + XOHCL GetBar(int barIndex) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + int totalBars = CountBars(); + if (barIndex >= totalBars) + { + barIndex = totalBars - 1; + } + + // + XOHCL result; + result.Init( + this.symbol, + this.period, + barIndex + // + ); + + // + return result; + } + + // + // Extract Specific Range of Bars ... + // using Start Bar Index ... + int GetBars( + XOHCL &result[], // Hold Result + int from = 0, // Start Bar Index + int count = 1, // Number of Bars + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + if (from < 0) + { + from = 0; + } + + // + int total = Bars( + symbol, + period); + if (from > total - 2) + { + from = total - 2; + } + + // + if (count < 0) + { + count = 1; + } + + // + int start = from; + int end = start + count; + if (end > total - 1) + { + end = total - 1; + } + + // + if (forceClean) + { + Clean(result); + } + + // + int beforeSize = ArraySize(result); + + // + for (int i = start; i < end; i++) + { + // + XOHCL iBar; + bool isValid = iBar.Init( + symbol, + period, + i + // + ); + + // + if (isValid) + { + // + AddRef( + iBar, + result + // + ); + } + } + + // + int afterSize = ArraySize(result); + + // + mResult = afterSize - beforeSize; + + // + return mResult; + } + + // + // Extract Specific Range of Bars ... + // using Start Bar Time ... + int GetBars( + XOHCL &result[], // Hold Result + datetime from = NULL, // Start Bar Time + int count = 1, // Number of Bars + bool forceClean = true // Clean Result Array + ) + { + // + from = NormalizeTime(from); + + // + int barIndex = iBarShift( + symbol, + period, + from, + false + // + ); + + // + return GetBars( + result, + symbol, + period, + barIndex, + count, + forceClean + // + ); + } + + // + // Retrieve Bar Time ... + datetime GetBarTime(int barIndex) + { + // + datetime result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + int totalBars = CountBars(); + if (barIndex >= totalBars) + { + barIndex = totalBars - 1; + } + + // + result = iTime( + this.symbol, + this.period, + barIndex + // + ); + + // + return result; + } + + // + // Find Chart ID ... + ulong GetChartID() + { + // + ulong result = 0; + + // + long firstChart = ChartFirst(); + result = firstChart; + + // + while (result >= 0) + { + // + string chSymbol = ChartSymbol(result); + ENUM_TIMEFRAMES chPeriod = ChartPeriod(result); + + // + bool isOwnChart = + // + symbol == chSymbol && + period == chPeriod + // + ; + if (isOwnChart) + { + break; + } + + // + result = ChartNext(result); + if (result < 0) + { + break; + } + } + + // + return result; + } + + // + // Create and String Representation for Unique Taging ... + string ToString() + { + // + string result = ""; + + // + if (!IsValid()) + { + return result; + } + + // + result = + GetTypeName(this) + "(" + + "PRFX(" + this.prefix + ")" + + "SMBL(" + this.symbol + ")" + + "CYC(" + ToString(this.cycle) + ")" + + "PRD(" + ToString(this.period) + ")" + + "PRDHST(" + ToString(this.hostPeriod) + ")" + + "MTH(" + EnumToString(this.method) + ")" + + ")"; + + // + return result; + } + + // + // Here we Produce a Summary brief of + // state of Cycle ... + string GenerateSummary() + { + // + string result = ""; + + // + bool hasPrefix = + StringLen(this.prefix) > 0 && + this.prefix != ToString(this.cycle); + result += (hasPrefix ? this.prefix + "[" : "") + + ToString(this.cycle) + + (hasPrefix ? "]" : "") + "\n"; + + // + result += " - PR: " + ToString(this.period) + "\n"; + + // + XOHCL cBar = GetBar(0); + + // + result += " - State: " + (cBar.IsBullish() ? "Bullish" : cBar.IsBearish() ? "Bearish" + : "Neutural"); + + // + return result; + } +}; + +// +// Functions ... + +// +// Validators ... + +// +// Validate an String has length and not NULL ... +bool IsValid(string value) +{ + // + bool result = false; + + // + result = + // + value != NULL && + StringLen(value) > 0 + // + ; + + // + return result; +} +bool IsSpecifiedValid(string value) +{ + return IsValid(value); +} + +// +// Validate a Date ... +bool IsValid(datetime value) +{ + // + bool result = false; + + // + result = NotEmpty(value) && value != NULL; + + // + return result; +} + +// +// Validate a Period Param ... +bool IsValid(ENUM_TIMEFRAMES value) +{ + // + bool result = false; + + // + result = + // + value != NULL + // + ; + + // + return result; +} +bool IsSpecifiedValid(ENUM_TIMEFRAMES value) +{ + // + return IsValid(value); +} + +// +// Validate Specified Cycle ... +bool IsValid(ENUM_X_MARKET_CYCLES value) +{ + // + bool result = false; + + // + result = + // + value != NULL && + value != X_MARKET_CYCLE_UNKNOWN + // + ; + + // + return result; +} + +// +// Validate Specific Period Mode ... +bool IsValid( + ENUM_X_PERIOD_METHOD mMethod, // Period Select Method + ENUM_TIMEFRAMES mPeriod // Selected Period +) +{ + // + bool result = false; + + // + result = + // + mMethod == X_PERIOD_NOTHING + ? false + : mMethod == X_PERIOD_MANUALLY + ? mPeriod != NULL + : mMethod == X_PERIOD_AUTO + ? true + : false + // + ; + + // + return result; +} + +// +bool IsSpecifiedValid( + ENUM_X_PERIOD_METHOD mMethod, // Period Select Method + ENUM_TIMEFRAMES mPeriod // Selected Period +) +{ + return IsValid(mMethod, + mPeriod // + ); +} + +// +// Validate Swing Mode ... +bool IsValid(ENUM_X_SWING_TYPE value) +{ + // + bool result = false; + + // + result = + // + value == X_SWING_HIGH || + value == X_SWING_LOW + // + ; + + // + return result; +} + +// +// As IS ... + +// +// Determine a Position type is Long or not ... +bool IsLong(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_BUY; + + // + return result; +} +bool IsLong(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_BUY; + + // + return result; +} + +// +// Determine a Position type is Short or not ... +bool IsShort(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_SELL; + + // + return result; +} +bool IsShort(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_SELL; + + // + return result; +} + +// +// Check Expert Running in Testing Mode or not ... +bool IsRunningOnTestMode() +{ + // + bool result = false; + + // + // check programm mode ... + result = MQL5InfoInteger(MQL5_TESTING); + + // + return result; +} + +// +// Find Chart ID ... +long FindChartID( + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period +) +{ + // + long result = ChartFirst(); + long first = result; + + // + while (result > 0) + { + // + string chSymbol = ChartSymbol(result); + ENUM_TIMEFRAMES chPeriod = ChartPeriod(result); + + // + bool isOwn = + // + chSymbol == mSymbol && + chPeriod == mPeriod + // + ; + if (isOwn) + { + break; + } + + // + result = ChartNext(result); + } + + // + return result; +} + +// +// Normalizers ... + +// +// Check a Symbol provided or not ... +// if not use Default ... +string NormalizeSymbol(string value) +{ + // + string result = value; + + // + if (!IsValid(result)) + { + result = _Symbol; + } + + // + return result; +} + +// +// Check a Datetime provided or not ... +// if not use Current ... +datetime NormalizeTime(datetime value) +{ + // + datetime result = value; + + // + if (!IsValid(result)) + { + result = TimeCurrent(); + } + + // + return result; +} + +// +// Check a Period provided or not ... +// if not use Default ... +ENUM_TIMEFRAMES NormalizePeriod(ENUM_TIMEFRAMES value) +{ + // + ENUM_TIMEFRAMES result = value; + + // + if (!IsValid(value)) + { + result = _Period; + } + + // + return result; +} + +// +// Normalize Cycle ... +ENUM_X_MARKET_CYCLES NormalizeCycle(ENUM_X_MARKET_CYCLES value) +{ + // + ENUM_X_MARKET_CYCLES result = value; + + // + if (!IsValid(result)) + { + result = X_MARKET_CYCLE_SHORT; + } + + // + return value; +} + +// +// Validate a Buffer Size for Looping or etc ... +bool IsValidSize(int size) +{ + // + bool result = size > 0; + + // + return result; +} + +// +// Normalize Index Based On Specified Buffer ... +template +void NormalizeIndex( + int &index, + T &buffer[] // +) +{ + // + int bufferSize = ArraySize(buffer); + + // + if (bufferSize <= 0) + { + index = 0; + } + + // + if (index <= 0) + { + index = 0; + } + + // + if (index > bufferSize - 1) + { + index = bufferSize - 1; + } +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double mVolume, // desired volume to normalize + string mSymbol = NULL, // Trading Symbol + int mLength = 2 // Length of Digits +) +{ + // + double result = mVolume; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + // Normalize Digits ... + int digits = GetDigits(mSymbol); + + // + mLength = + mLength == 0 || mLength > digits + ? digits + : MathMin(mLength, digits); + + // + // Normalize Volume ... + result = NormalizeDouble(result, mLength); + + // + double maxAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double mPrice, // desired Price for normalization + string mSymbol = NULL // Trading Symbol +) +{ + // + double result = 0; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + double tickSize = 0; + result = SymbolInfoDouble(mSymbol, SYMBOL_TRADE_TICK_SIZE, tickSize); + + // + int digits = GetDigits(mSymbol); + result = NormalizeDouble(MathRound(mPrice / tickSize) * tickSize, digits); + + // + return result; +} + +// +// Prices ... + +// +// Retrieve Ask Price ... +double GetAsk( + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + + // + double result = SymbolInfoDouble(mSymbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid( + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + + // + double result = SymbolInfoDouble(mSymbol, SYMBOL_BID); + + // + return result; +} + +// +// Retrieve Spread Price ... +double GetSpread( + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + + // + double ask = GetAsk(mSymbol); + double bid = GetBid(mSymbol); + + // + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Retrieve Point Value ... +double GetPoints( + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + + // + double result = SymbolInfoDouble(mSymbol, SYMBOL_POINT); + + // + return result; +} + +// +// Retrieve Point Digits ... +int GetDigits( + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + + // + int result = (int)SymbolInfoInteger(mSymbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Retrieve Entry Price ... +double GetEntry( + string mSymbol = NULL, // Trading Symbol + ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + result = + IsLong(type) + ? GetAsk(mSymbol) + : GetBid(mSymbol); + result = NormalizePrice(result, mSymbol); + + // + return result; +} + +// +// Retrieve Exit Price ... +double GetExit( + string mSymbol = NULL, // Trading Symbol + ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + result = + IsLong(type) + ? GetBid(mSymbol) + : GetAsk(mSymbol); + result = NormalizePrice(result, mSymbol); + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice( + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + + // + double symbolPoint = GetPoints(mSymbol); + int symbolDigits = GetDigits(mSymbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + double mPips, // pips amount + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + + // + int digits = GetDigits(mSymbol); + double pipValue = GetPipPrice(mSymbol); + double result = mPips * pipValue; + + // + result = NormalizePrice(result, mSymbol); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double mPrice, // the price amount which required to calculate + string mSymbol = NULL // Trading Symbol +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + mPrice = NormalizePrice(mPrice, mSymbol); + + // + int digits = GetDigits(mSymbol); + double pipPrice = GetPipPrice(mSymbol); + + // + double result = mPrice / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Convert Price to Point ... +double PriceToPoint( + double price, // the price amount which required to calculate + string mSymbol = NULL // Trading Symbol +) +{ + // + double result = 0; + + // + mSymbol = NormalizeSymbol(mSymbol); + price = NormalizePrice(price, mSymbol); + + // + double point = GetPoints(mSymbol); + result = price / point; + + // + return result; +} + +// +// Converts Point to Price ... +double PointToPrice( + double points, // Points Amount + string mSymbol = NULL // Trading Symbol +) +{ + // + double result = 0; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + double point = GetPoints(mSymbol); + result = points * point; + + // + result = NormalizePrice(result, mSymbol); + + // + return result; +} + +// +// Converts Series Mode to XPRICE ... +ENUM_X_PRICE ToPrice( + ENUM_SERIESMODE mMode // Specified Series Mode ... +) +{ + // + ENUM_X_PRICE result = X_PRICE_CLOSE; + + // + switch (mMode) + { + // + // High ... + case MODE_HIGH: + result = X_PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = X_PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = X_PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = X_PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve Applied Price ... +template +double GetAppliedPrice( + ENUM_APPLIED_PRICE tprice, // Type of Price Selection + T &open[], // Open Prices + T &high[], // High Preices + T &low[], // Low Prices + T &close[], // Close Prices + int i // Bar Index +) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} + +// +// Symbols ... + +// +// Retrieve Available Symbols ... +int GetAllSymbols( + string &symbols[], // Hold Result + bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List + bool forceClean = true // Force To Clean Result Array +) +{ + // + int result = 0; + + // + if (forceClean) + { + Clean(symbols); + } + + // + int beforeSize = ArraySize(symbols); + + // + int symbolsCount = SymbolsTotal(onlyInWatchList); + if (symbolsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < symbolsCount; i++) + { + // + string iSymbol = SymbolName( + i, + onlyInWatchList + // + ); + if (!IsValid(iSymbol)) + { + continue; + } + + // + Add( + iSymbol, + symbols + // + ); + } + + // + int afterSize = ArraySize(symbols); + + // + result = afterSize - beforeSize; + + // + return result; +} + +// +// This is a Global Way to Filter Symbols +// you can pass Specific string as Query or a List String for Filtering ... +int FilterSymbols( + string query, // Which Query to Search Symbol + string &symbols[], // Hold Result + bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List + bool forceClean = true, // Force To Clean Result Array + bool ignoreCase = true, // Ignore Case + string querySeparator = "," // If Provided means query is a COllection of Queries and need to be Splitted +) +{ + // + int result = 0; + + // + if (forceClean) + { + Clean(symbols); + } + + // + if (!IsValid(query)) + { + return result; + } + + // + // Check Query is an String array or not ... + string mQueries[]; + int queriesCount = 0; + if (IsValid(querySeparator) && Contains(querySeparator, query, true)) + { + // + queriesCount = SplitContent( + mQueries, + query, + querySeparator + // + ); + } + + // + int beforeSize = ArraySize(symbols); + + // + string allSymbols[]; + int allSymbolsCount = GetAllSymbols( + allSymbols, + onlyInWatchList, + forceClean); + if (allSymbolsCount <= 0) + { + return result; + } + + // + // Loop Through all Symbols ... + for (int i = 0; i < allSymbolsCount; i++) + { + // + string iSymbol = allSymbols[i]; + + // + bool isFilterPassed = false; + if (queriesCount == 0) + { + // + isFilterPassed = Contains( + query, + iSymbol, + ignoreCase + // + ); + } + else if (queriesCount > 0) + { + // + isFilterPassed = Contains( + mQueries, + iSymbol, + ignoreCase + // + ); + } + + // + if (isFilterPassed) + { + // + Add( + iSymbol, + symbols + // + ); + } + } + + // + int afterSize = ArraySize(symbols); + + // + result = afterSize - beforeSize; + + // + return result; +} + +// +int FilterUSDSymbols( + string &symbols[], // Hold Result + bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List + bool forceClean = true, // Force To Clean Result Array + bool ignoreCase = true, // Ignore Case + string querySeparator = "," // If Provided means query is a COllection of Queries and need to be Splitted +) +{ + // + return FilterSymbols( + "USD", + symbols, + onlyInWatchList, + forceClean, + ignoreCase, + querySeparator + // + ); +} + +// +// Time / Date ... + +// +// Representation of Time Struct ... +// struct MqlDateTime +// { +// int year; // Year +// int mon; // Month +// int day; // Day +// int hour; // Hour +// int min; // Minutes +// int sec; // Seconds +// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) +// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) +// }; + +// +// Converts Time to Seconds ... +ulong TimeToSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = (ulong)time; + + // + return result; +} +ulong TimeToSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToSeconds(dTime); + + // + return result; +} + +// +// Converts Seconds To Time ... +datetime SecondsToTime( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime result = (datetime)seconds; + + // + return result; +} +MqlDateTime SecondsToStruct( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime dTime = SecondsToTime(seconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Converts Time to MilliSeconds ... +ulong TimeToMilliSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = TimeToSeconds(time) * 1000; + + // + return result; +} +ulong TimeToMilliSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToMilliSeconds(dTime); + + // + return result; +} + +// +// Converts MillisSeconds to Time ... +datetime MilliSecondsToTiem( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + ulong seconds = milliSeconds / 1000; + + // + datetime result = SecondsToTime(seconds); + + // + return result; +} +MqlDateTime MilliSecondsToStruct( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + datetime dTime = MilliSecondsToTiem(milliSeconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Retrieve DateTime Structure ... +MqlDateTime GetCurrentTime() +{ + // + MqlDateTime result = {}; + + // + TimeCurrent(result); + + // + return result; +} + +// +// Retrieve Current Time as Seconds ... +ulong GetCurrentTimeAsSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Current Time as MilliSeconds ... +ulong GetCurrentTimeAsMilliSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Bar Times ... + +// +// Retrieve Specified Bar Time ... +datetime GetBarTime( + string mSymbol = "", // Specify Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame + int barIndex = 0 // Specify Bar Index +) +{ + // + // Validate and Normalize Args ... + + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + // Retrieve Bar Time ... + datetime result = iTime( + mSymbol, + mPeriod, + barIndex); + + // + return result; +} + +// +// Retrieve Specified Bar Time ... +ulong GetBarTimeAsSeconds( + string mSymbol = "", // Specify Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame + int barIndex = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetBarTime( + mSymbol, + mPeriod, + barIndex); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Bar Time ... +ulong GetBarTimeAsMilliSeconds( + string mSymbol = "", // Specify Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame + int barIndex = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetBarTime( + mSymbol, + mPeriod, + barIndex); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve a Bar Time Structure ... +MqlDateTime GetBarTimeStruct( + string mSymbol = "", // Specify Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame + int barIndex = 0 // Specify Bar Index +) +{ + // + MqlDateTime result = {}; + + // + // Retrieve Bar Time ... + datetime barTime = GetBarTime( + mSymbol, + mPeriod, + barIndex); + + // + // Convert to Structure ... + TimeToStruct(barTime, result); + + // + return result; +} + +// +// Other Tools ... + +// +template +bool IsSame( + T &buffer[], // Search Buffer + int count = 5, // Number of Searchs + int start = 0 // Start ... +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + result = bufferSize > 0; + if (!result) + { + return result; + } + + // + // Validate Count ... + result = start + count < bufferSize; + if (!result) + { + return result; + } + + // + T iTem = buffer[start]; + for (int i = start; i < start + count; i++) + { + // + if (iTem != buffer[i]) + { + result = false; + break; + } + + // + if (!result) + { + result = true; + } + } + + // + return result; +} + +// +// Check first Cross Over second at index ... +bool IsCrossedOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int index = 0 // check crosses in specific index +) +{ + // + bool result = false; + + // + // Validate Args ... + if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) + { + return result; + } + + // + result = first[index] > second[index] && + !(first[index + 1] > second[index + 1]); + + // + return result; +} + +// +// Check first is Over second at index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int index = 0 // check crosses in specific index +) +{ + // + bool result = false; + + // + // Validate Args ... + if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) + { + return result; + } + + // + result = first[index] > second[index] && + first[index + 1] > second[index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at index ... +bool IsCrossedUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int index = 0 // check crosses in specific index +) +{ + // + bool result = false; + + // + // Validate Args ... + if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) + { + return result; + } + + // + result = first[index] < second[index] && + !(first[index + 1] < second[index + 1]); + + // + return result; +} + +// +// Check first is Under second at index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int index = 0 // check crosses in specific index +) +{ + // + bool result = false; + + // + // Validate Args ... + if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) + { + return result; + } + + // + result = first[index] < second[index] && + first[index + 1] < second[index + 1]; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + const int from, // Last Time Index + const int to, // Fisrs Tima Index + const double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + const int from, // Last Time Index + const int to, // Fisr Tima Index + const double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +bool IsTrendingUp( + const double &buffer1[], // First Buffer + const double &buffer2[] // Seccend Buffer +) +{ + // + bool result = false; + + // + int buffer1Count = ArraySize(buffer1); + int buffer2Count = ArraySize(buffer2); + if (buffer1Count <= 0 || buffer2Count <= 0) + { + return result; + } + + // + int count = MathMin(buffer1Count, buffer2Count); + if (count <= 1) + { + return result; + } + + // + int upCounts = 0; + int downCounts = 0; + double value = MathAbs(buffer1[0] - buffer2[0]); + for (int i = 1; i < count; i++) + { + // + double iValue = MathAbs(buffer1[i] - buffer2[i]); + + // + if (value > iValue) + { + upCounts++; + } + + // + if (value < iValue) + { + downCounts++; + } + } + + // + result = upCounts > 1 && upCounts > downCounts; + + // + return result; +} + +// +bool IsTrendingDown( + const double &buffer1[], // First Buffer + const double &buffer2[] // Seccend Buffer +) +{ + // + bool result = false; + + // + int buffer1Count = ArraySize(buffer1); + int buffer2Count = ArraySize(buffer2); + if (buffer1Count <= 0 || buffer2Count <= 0) + { + return result; + } + + // + int count = MathMin(buffer1Count, buffer2Count); + if (count <= 1) + { + return result; + } + + // + int upCounts = 0; + int downCounts = 0; + double value = MathAbs(buffer1[0] - buffer2[0]); + for (int i = 1; i < count; i++) + { + // + double iValue = MathAbs(buffer1[i] - buffer2[i]); + + // + if (value > iValue) + { + upCounts++; + } + + // + if (value < iValue) + { + downCounts++; + } + } + + // + result = downCounts > 1 && downCounts > upCounts; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + const double &buffer[], // Buffer + int from, // In Past Index ... + int to // In Past Index ... +) +{ + // + double result = 0; + + // + if (from > ArraySize(buffer) || to > ArraySize(buffer)) + { + return result; + } + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, // Upper Bound + double downPrice, // Downer Bound + double level, // Level Multiplier Factor + int direction // From Down to Up < 0, other wise Vice Versa + // +) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + + // + return result; +} + +// +// Templates ... + +// +// Retrieve Specific Object Types Name ... +template +string GetTypeName(const T &t) +{ + return typename(T); +} + +// +template +string GetToken(T &item) +{ + // + string mType = GetTypeName(item); + + // + string result = mType; + + // + string parts[]; + int partsCount = SplitContent( + parts, + result, + " " + // + ); + if (partsCount <= 0) + { + // + result = mType; + return result; + } + + // + bool hasLastPart = GetLastItem( + result, + parts + // + ); + if (!hasLastPart) + { + // + result = mType; + return result; + } + + // + return result; +} + +// +// Same as Get Token for Use in Classes ... +template +string GetSpecificToken(T &item) +{ + // + string mType = GetTypeName(item); + + // + string result = mType; + + // + string parts[]; + int partsCount = SplitContent( + parts, + result, + " " + // + ); + if (partsCount <= 0) + { + // + result = mType; + return result; + } + + // + bool hasLastPart = GetLastItem( + result, + parts + // + ); + if (!hasLastPart) + { + // + result = mType; + return result; + } + + // + return result; +} + +// +// Generate Unique Tags ... +template +string GenerateTag(T &model) +{ + // + string result = ""; + + // + string tag = model.ToString(); + if (StringLen(tag) == 0) + { + return result; + } + + // + static XSCMD5 md5; + + // + result = md5.Hash(tag); + + // + return result; +} + +// +// Hash Specified Content ... +template +string ToMD5(T content) +{ + // + string result = ""; + + // + string strContent = ToString(content); + if (StringLen(strContent) == 0) + { + return result; + } + + // + static XSCMD5 md5; + + // + result = md5.Hash(strContent); + + // + return result; +} + +// +// Check a Value Not Empty ... +template +bool NotEmpty(T value) +{ + return value != EMPTY_VALUE; +} + +// +// Add Specified Item to Array ... +template +int Add( + T item, // item want to add + T &buffer[] // Destination buffer +) +{ + // + int result = 0; + + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; + + // + result = ArraySize(buffer); + + // + return result; +} +template +int AddSpecific( + T item, // item want to add + T &buffer[] // Destination buffer +) +{ + // + return Add( + item, + buffer // + ); +} +template +int AddRef( + T &item, // item want to add + T &buffer[] // Destination buffer +) +{ + // + int result = 0; + + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; + + // + result = ArraySize(buffer); + + // + return result; +} + +// +// Remove Specified Item from an Array ... +template +bool Remove( + T item, + T &buffer[]) +{ + // + bool result = false; + + // + int itemIndex = FindIndex( + item, + buffer); + if (itemIndex < 0) + { + return result; + } + + // + result = ArrayRemove( + buffer, + itemIndex, + 1); + + // + return result; +} + +// +// Clean Specified Array ... +template +void Clean(T &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// Copy Whole Content of Source to Dest array ... +template +void Copy( + T &source[], // Source Buffer ... + T &dest[], // Dest Buffer ... + bool cleanDest = true // Force Clen Dest Buffer ... +) +{ + // + if (cleanDest) + { + Clean(dest); + } + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + T iSource = source[i]; + + // + AddRef( + iSource, + dest); + } +} + +// +// Copy Items from a Buffer ... +template +int Copy( + int start, // Start + int count, // Number of Items for read + T &source[], // Source Buffer + T &dest[], // Dest Buffer + bool forceClean = true // Force To Clean buffer +) +{ + // + int result = 0; + + // + if (forceClean) + { + Clean(dest); + } + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(source)) + { + start = ArraySize(source) - 1; + } + + // + if (count == 0) + { + count = ArraySize(source); + } + + // + if (start + count > ArraySize(source)) + { + return result; + } + + // + int beforeSize = ArraySize(dest); + + // + bool asSeriesDest = ArrayGetAsSeries(dest); + bool asSeriesSource = ArrayGetAsSeries(source); + + // + ArraySetAsSeries(dest, true); + ArraySetAsSeries(source, true); + + // + ArrayCopy( + dest, + source, + 0, + start, + count + // + ); + + // + int afterSize = ArraySize(dest); + + // + result = afterSize - beforeSize; + + // + ArraySetAsSeries(dest, asSeriesDest); + ArraySetAsSeries(source, asSeriesSource); + + // + return result; +} + +// +// Copy Items from a Buffer ... +template +int CopyRef( + int start, // Start + int count, // Number of Items for read + T &source[], // Source Buffer + T &dest[], // Dest Buffer + bool forceClean = true // Force To Clean buffer +) +{ + // + int result = 0; + + // + if (forceClean) + { + Clean(dest); + } + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(source)) + { + start = ArraySize(source) - 1; + } + + // + int beforeSize = ArraySize(dest); + + // + bool asSeriesDest = ArrayGetAsSeries(dest); + bool asSeriesSource = ArrayGetAsSeries(source); + + // + ArraySetAsSeries(dest, true); + ArraySetAsSeries(source, true); + + // + for (int i = start; i < start + count; i++) + { + // + AddRef( + source[i], + dest + // + ); + } + + // + int afterSize = ArraySize(dest); + + // + result = afterSize - beforeSize; + + // + ArraySetAsSeries(dest, asSeriesDest); + ArraySetAsSeries(source, asSeriesSource); + + // + return result; +} + +// +// Retrive Last Item of Specified Buffer ... +template +bool GetLastItem( + T &item, // Holds Result + T &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} + +// +// Search Array For Specific Item ... +template +int FindIndex( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + int result = -1; + + // + int count = ArraySize(buffer); + if (count <= 0) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T iT = buffer[i]; + + // + if (iT == item) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Check an Array Contains Specified Value ... +template +bool Contains( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + bool result = false; + + // + int idx = FindIndex( + item, + buffer); + result = idx > -1; + + // + return result; +} + +// +// Calculate a Buffer's Average ... +template +double GetAverage( + T &buffer[], // the Buffer which required to search + int start = 0, // Start Index + int count = 0 // Count for Search +) +{ + // + double result = 0; + + // + T tmp[]; + int tmpCount = Copy( + start, + count, + buffer, + tmp + // + ); + if (tmpCount <= 0) + { + return result; + } + + // + // Calculate Summary ... + for (int i = 0; i < tmpCount; i++) + { + result += buffer[i]; + } + + // + // Calculate Average ... + result = result / tmpCount; + + // + return result; +} + +// +// Get Max of Specific Loopback of a Buffer ... +template +double GetMax( + T &buffer[], // the Buffer which required to search + int start = 0, // Start Index + int count = 0 // Count for Search +) +{ + // + double result = 0; + + // + if (count <= 0) + { + count = ArraySize(buffer); + } + + // + T tmp[]; + int tmpCount = Copy( + start, + count, + buffer, + tmp + // + ); + if (tmpCount <= 0) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min of Specific Loopback of a Buffer ... +template +double GetMin( + T &buffer[], // the Buffer which required to search + int start = 0, // Start Index + int count = 0 // Count for Search +) +{ + // + double result = 0; + + // + if (count <= 0) + { + count = ArraySize(buffer); + } + + // + T tmp[]; + int tmpCount = Copy( + start, + count, + buffer, + tmp + // + ); + if (tmpCount <= 0) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Find a Value less than Specified ... +template +T FindLesserThan( + T value, // Specified Value ... + const T &source[], // Source ... + bool isDescend = false // Find Biggest Lesser Value ... +) +{ + // + T result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + T tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + T iValue = tmp[i]; + + // + if (iValue < value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +template +T FindBiggerThan( + T value, // Specified Value ... + const T &source[], // Source ... + bool isDescend = false // Find Smallest Bigger Value ... +) +{ + // + T result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + T tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (!isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + T iValue = tmp[i]; + + // + if (iValue > value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Find Same Values in Array ... +template +void FindSames( + T &result[], // Holds Result ... + T &source[], // Source ... + int verifications = 3 // Number of Consequence Repeat ... +) +{ + // + Clean(result); + + // + // TenkanSen Flats ... + int sourceCount = ArraySize(source); + if (sourceCount > verifications) + { + // + T mLast = 0; + int mVerified = 0; + for (int i = 0; i < sourceCount; i++) + { + // + T iVal = source[i]; + if (mLast == 0) + { + mLast = iVal; + } + else if (mLast == iVal) + { + mVerified++; + } + else + { + mLast = iVal; + mVerified = 0; + } + + // + if (iVal == mLast && mVerified >= verifications) + { + // + Add( + iVal, + result); + + // + mLast = 0; + mVerified = 0; + } + } + } +} + +// +// Add an Item to a Buffer if not Exists ... +void AddIfNotExists( + double value, + double &values[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int valuesCount = ArraySize(values); + if (valuesCount <= 0) + { + // + Add(value, + values); + } + else + { + // + bool isExists = false; + for (int i = 0; i < valuesCount; i++) + { + // + double iVal = values[i]; + + // + double diff = MathAbs(iVal - value); + + // + if (iVal == value || diff < smoothingValue) + { + // + isExists = true; + break; + } + } + + // + if (!isExists) + { + // + Add(value, + values); + } + } +} + +// +// Add a Buffers Child to another Buffer +// if it's not Contains them ... +void AddsIfNotExists( + double &source[], + double &dest[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + double iSource = source[i]; + + // + AddIfNotExists( + iSource, + dest, + smoothingPoint); + } +} + +// +// Bar XOHCL ... + +// +// Extract Specific Range of Bars ... +// using Start Bar Index ... +int GetBars( + XOHCL &result[], // Hold Result + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame + int from = 0, // Start Bar Index + int count = 1, // Number of Bars + bool forceClean = true // Clean Result Array +) +{ + // + int mResult = 0; + + // + if (from < 0) + { + from = 0; + } + + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + int total = Bars( + mSymbol, + mPeriod); + if (from > total - 2) + { + from = total - 2; + } + + // + if (count < 0) + { + count = 1; + } + + // + int start = from; + int end = start + count; + if (end > total - 1) + { + end = total - 1; + } + + // + if (forceClean) + { + Clean(result); + } + + // + int beforeSize = ArraySize(result); + + // + for (int i = start; i < end; i++) + { + // + XOHCL iBar; + bool isValid = iBar.Init( + mSymbol, + mPeriod, + i + // + ); + + // + if (isValid) + { + // + AddRef( + iBar, + result + // + ); + } + } + + // + int afterSize = ArraySize(result); + + // + mResult = afterSize - beforeSize; + + // + return mResult; +} + +// +// Extract Specific Range of Bars ... +// using Start Bar Time ... +int GetBars( + XOHCL &result[], // Hold Result + string mSymbol = NULL, // Trading Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame + datetime from = NULL, // Start Bar Time + int count = 1, // Number of Bars + bool forceClean = true // Clean Result Array +) +{ + // + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + from = NormalizeTime(from); + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + from, + false + // + ); + + // + return GetBars( + result, + mSymbol, + mPeriod, + barIndex, + count, + forceClean + // + ); +} + +// +// String ... + +// +// Search a Content Contains Specific String or not ... +bool Contains( + string mQuery, // Search String + string mContent, // Search Content + bool ignoreCase = true // Ignore Case +) +{ + // + bool result = false; + + // + // Validate Query ... + result = IsValid(mQuery); + if (!result) + { + return result; + } + + // + // Validate Content ... + result = IsValid(mContent); + if (!result) + { + return result; + } + + // + // Normalize Inputs ... + string query = mQuery; + string content = mContent; + if (ignoreCase) + { + // + StringToLower(query); + StringToLower(content); + } + + // + int queryIdx = StringFind( + content, + query); + + // + result = queryIdx >= 0; + + // + return result; +} + +// +bool Contains( + string &mQueries[], // Search Strings + string mContent, // Search Content + bool ignoreCase = true // Ignore Case +) +{ + // + bool result = false; + + // + // Validate Queries ... + int queriesCount = ArraySize(mQueries); + result = queriesCount > 0; + if (!result) + { + return result; + } + + // + // Validate Content ... + result = IsValid(mContent); + if (!result) + { + return result; + } + + // + int containsCount = 0; + for (int i = 0; i < queriesCount; i++) + { + // + bool isContains = Contains( + mQueries[i], + mContent, + ignoreCase); + + // + if (!isContains) + { + // + result = false; + break; + } + + // + containsCount++; + } + + // + result = containsCount == queriesCount; + + // + return result; +} + +// +// Convert From String ... +template +T FromString(string value) +{ + // + T result = NULL; + + // + if (!IsValid(value)) + { + return result; + } + + // + result = (T)value; + + // + return result; +} + +// +// Converts an item to String ... +template +string ToString(T value) +{ + return (string)value; +} + +// +// Used In Report or Summary Generators ... +string ToString( + string prefix, // Title + bool value, // Value + bool ignoreFalseConditions = true, // Ignore False Conditions + string prefixSeparator = ":", // Title Separator + string lineSeparator = "\n" // Line Separator +) +{ + // + string result = NULL; + + // + result = (value || !ignoreFalseConditions) + ? prefix + + prefixSeparator + " " + + ToString(value) + + lineSeparator + : ""; + + // + return result; +} + +// +string SetLabel( + string mLabel, // Provided Label ... + string value, // Source Value ... + string separator = "\n", // Line Separator + bool addTopEmptyLine = true // Add Empty Line On top +) +{ + // + string result = value; + + // + if (StringLen(mLabel) <= 0) + { + return result; + } + + // + result = (StringLen(value) > 0) + ? (addTopEmptyLine ? separator : "") + + mLabel + + separator + + "-----------------------------" + + separator + + value + : value; + + // + return result; +} + +// +// Converts a Buffer to String Representation ... +template +string ToString( + const T &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} + +// +// Converts String to boolean ... +bool ToBoolean(string value) +{ + // + bool result = false; + + // + if (StringLen(value) <= 0) + { + return result; + } + + // + StringToLower(value); + result = value == "true"; + + // + return result; +} + +// +// Split an String Representation of an Array ... +int SplitContent( + string &result[], // Hold Result ... + string content, // Source ... + string separator = ",", // Separator ... + bool forceCleanResult = true // Clean Result ... +) +{ + // + int mResult = 0; + + // + if (forceCleanResult) + { + Clean(result); + } + + // + int before = ArraySize(result); + + // + if (separator == NULL || StringLen(separator) == 0) + { + separator = ","; + } + + // + if (StringLen(content) == 0) + { + return mResult; + } + + // + StringSplit( + content, + StringGetCharacter( + separator, + 0), + result); + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Extract an Array of Contents ... +int ExtractStrings( + string &result[], // Hold Result + const string source, // Source String used for Extracting + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + // Validate Args ... + int sourceLength = StringLen(source); + int startLength = StringLen(startString); + int endLength = StringLen(endString); + + // + int minRequiredLength = startLength + endLength; + + // + if ( + endLength <= 0 || + startLength <= 0 || + sourceLength <= 0 || + sourceLength < minRequiredLength) + { + return mResult; + } + + // + // Make a Copy of Source for Manipulating ... + string workStr = source; + + // + // Define a Loop ... + while (StringLen(workStr) > minRequiredLength) + { + // + // Find Item ... + string item = ExtractString( + workStr, + startString, + endString); + + // + // Breakout when couldn't find anymore item ... + int itemLength = StringLen(item); + if (itemLength <= 0) + { + break; + } + + // + // Prepare Item Source String for Replacing in Work String ... + string itemSource = startString + item + endString; + + // + // Add Item to Result Array ... + Add( + item, + result); + + // + // Replace Item Soure in Work String ... + StringReplace( + workStr, + itemSource, + ""); + } + + // + // Calculate Size of Array ... + mResult = ArraySize(result); + + // + return mResult; +} + +// +string ExtractSurrounded( + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + return ExtractString( + surrounded, + mToken + startString, + endString + // + ); +} + +// +int ParseIntSurrounded( + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + int result = NULL; + + // + string strContent = ExtractSurrounded( + surrounded, + mToken, + startString, + endString + // + ); + if (!IsValid(strContent)) + { + return result; + } + + // + result = (int)strContent; + + // + return result; +} +long ParseLongSurrounded( + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + long result = NULL; + + // + string strContent = ExtractSurrounded( + surrounded, + mToken, + startString, + endString + // + ); + if (!IsValid(strContent)) + { + return result; + } + + // + result = (long)strContent; + + // + return result; +} +string ParseStringSurrounded( + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + string result = NULL; + + // + string strContent = ExtractSurrounded( + surrounded, + mToken, + startString, + endString + // + ); + if (!IsValid(strContent)) + { + return result; + } + + // + result = (string)strContent; + + // + return result; +} +double ParseDoubleSurrounded( + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + double result = NULL; + + // + string strContent = ExtractSurrounded( + surrounded, + mToken, + startString, + endString + // + ); + if (!IsValid(strContent)) + { + return result; + } + + // + result = (double)strContent; + + // + return result; +} +datetime ParseTimeSurrounded( + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + const string startString = "(", // Expression Start String must be Unique + const string endString = ")" // Where to End Extraction, usually a Sign +) +{ + // + datetime result = NULL; + + // + string strContent = ExtractSurrounded( + surrounded, + mToken, + startString, + endString + // + ); + if (!IsValid(strContent)) + { + return result; + } + + // + result = (datetime)strContent; + + // + return result; +} + +// +int ParseIntArraySurrounded( + int &result[], // Holds Result + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + string separator = ",", // Separator ... + const string startString = "(", // Expression Start String must be Unique + const string endString = ")", // Where to End Extraction, usually a Sign + bool forceClean = true // Clean Result ... +) +{ + // + int count = 0; + + // + if (forceClean) + { + Clean(result); + } + + // + int before = ArraySize(result); + + // + string contentStr = ParseStringSurrounded(surrounded, mToken); + if (!IsValid(contentStr)) + { + return count; + } + + // + string tmps[]; + int tmpsCount = SplitContent( + tmps, + contentStr + // + ); + if (tmpsCount <= 0) + { + return count; + } + + // + for (int i = 0; i < tmpsCount; i++) + { + // + string iTMP = tmps[i]; + if (!IsValid(iTMP)) + { + continue; + } + + // + int iValue = (int)iTMP; + + // + Add( + iValue, + result + // + ); + } + + // + int after = ArraySize(result); + + // + count = after - before; + + // + return count; +} +int ParseLongArraySurrounded( + long &result[], // Holds Result + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + string separator = ",", // Separator ... + const string startString = "(", // Expression Start String must be Unique + const string endString = ")", // Where to End Extraction, usually a Sign + bool forceClean = true // Clean Result ... +) +{ + // + int count = 0; + + // + if (forceClean) + { + Clean(result); + } + + // + int before = ArraySize(result); + + // + string contentStr = ParseStringSurrounded(surrounded, mToken); + if (!IsValid(contentStr)) + { + return count; + } + + // + string tmps[]; + int tmpsCount = SplitContent( + tmps, + contentStr + // + ); + if (tmpsCount <= 0) + { + return count; + } + + // + for (int i = 0; i < tmpsCount; i++) + { + // + string iTMP = tmps[i]; + if (!IsValid(iTMP)) + { + continue; + } + + // + long iValue = (long)iTMP; + + // + Add( + iValue, + result + // + ); + } + + // + int after = ArraySize(result); + + // + count = after - before; + + // + return count; +} +int ParseDoubleArraySurrounded( + double &result[], // Holds Result + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + string separator = ",", // Separator ... + const string startString = "(", // Expression Start String must be Unique + const string endString = ")", // Where to End Extraction, usually a Sign + bool forceClean = true // Clean Result ... +) +{ + // + int count = 0; + + // + if (forceClean) + { + Clean(result); + } + + // + int before = ArraySize(result); + + // + string contentStr = ParseStringSurrounded(surrounded, mToken); + if (!IsValid(contentStr)) + { + return count; + } + + // + string tmps[]; + int tmpsCount = SplitContent( + tmps, + contentStr + // + ); + if (tmpsCount <= 0) + { + return count; + } + + // + for (int i = 0; i < tmpsCount; i++) + { + // + string iTMP = tmps[i]; + if (!IsValid(iTMP)) + { + continue; + } + + // + double iValue = (double)iTMP; + + // + Add( + iValue, + result + // + ); + } + + // + int after = ArraySize(result); + + // + count = after - before; + + // + return count; +} +int ParseTimeArraySurrounded( + datetime &result[], // Holds Result + const string surrounded, // Surrounded Content + const string mToken, // Specified Token + string separator = ",", // Separator ... + const string startString = "(", // Expression Start String must be Unique + const string endString = ")", // Where to End Extraction, usually a Sign + bool forceClean = true // Clean Result ... +) +{ + // + int count = 0; + + // + if (forceClean) + { + Clean(result); + } + + // + int before = ArraySize(result); + + // + string contentStr = ParseStringSurrounded(surrounded, mToken); + if (!IsValid(contentStr)) + { + return count; + } + + // + string tmps[]; + int tmpsCount = SplitContent( + tmps, + contentStr + // + ); + if (tmpsCount <= 0) + { + return count; + } + + // + for (int i = 0; i < tmpsCount; i++) + { + // + string iTMP = tmps[i]; + if (!IsValid(iTMP)) + { + continue; + } + + // + datetime iValue = (datetime)iTMP; + + // + Add( + iValue, + result + // + ); + } + + // + int after = ArraySize(result); + + // + count = after - before; + + // + return count; +} + +// +// Surround an String by Specific Token ... +template +string Surround( + string mToken, // an String which used to Tokenize + T &value, // a Value for Tokenize it + string startString = "(", // Token Start Content + string endString = ")" // Token End Content +) +{ + // + string result = NULL; + + // + string strValue = ToString(value); + if (!IsValid(strValue)) + { + return result; + } + + // + result = + // + (IsValid(mToken) + ? mToken + : "") + + // + startString + + strValue + + endString + // + ; + + // + return result; +} + +// +template +string SurroundArray( + string mToken, + T &value[], + string startString = "(", // Token Start Content + string endString = ")" // Token End Content +) +{ + // + string result = NULL; + + // + string valueStr = ToString(value); + if (!IsValid(valueStr)) + { + return result; + } + + // + result = Surround( + mToken, + valueStr, + startString, + endString + // + ); + + // + return result; +} + +// +// Periods / Cycles ... + +// +// Converts an String to TimeFrame ... +ENUM_TIMEFRAMES ToPeriod(string value) +{ + // + if (StringLen(value) == 0) + { + return _Period; + } + + // + StringTrimLeft(value); + StringTrimRight(value); + + // + ENUM_TIMEFRAMES result = _Period; + + // + if (value == "M1") + { + result = PERIOD_M1; + } + else if (value == "M2") + { + result = PERIOD_M2; + } + else if (value == "M3") + { + result = PERIOD_M3; + } + else if (value == "M4") + { + result = PERIOD_M4; + } + else if (value == "M5") + { + result = PERIOD_M5; + } + else if (value == "M6") + { + result = PERIOD_M6; + } + else if (value == "M10") + { + result = PERIOD_M10; + } + else if (value == "M12") + { + result = PERIOD_M12; + } + else if (value == "M15") + { + result = PERIOD_M15; + } + else if (value == "M20") + { + result = PERIOD_M20; + } + else if (value == "M30") + { + result = PERIOD_M30; + } + else if (value == "H1") + { + result = PERIOD_H1; + } + else if (value == "H2") + { + result = PERIOD_H2; + } + else if (value == "H3") + { + result = PERIOD_H3; + } + else if (value == "H4") + { + result = PERIOD_H4; + } + else if (value == "H6") + { + result = PERIOD_H6; + } + else if (value == "H8") + { + result = PERIOD_H8; + } + else if (value == "H12") + { + result = PERIOD_H12; + } + else if (value == "D1") + { + result = PERIOD_D1; + } + else if (value == "W1") + { + result = PERIOD_W1; + } + else if (value == "MN1") + { + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Converts Period to String ... +string ToString(ENUM_TIMEFRAMES mPeriod) +{ + // + string result = ""; + + // + string mPStr = EnumToString(mPeriod); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[1]; + + // + return result; +} + +// +// Retrieve All Available Period as an Array ...s +int GetAllAvailablePeriods( + ENUM_TIMEFRAMES &result[] // Holds Result ... +) +{ + // + Clean(result); + + // + Add( + PERIOD_M1, + result + // + ); + + // + Add( + PERIOD_M2, + result + // + ); + + // + Add( + PERIOD_M3, + result + // + ); + + // + Add( + PERIOD_M4, + result + // + ); + + // + Add( + PERIOD_M5, + result + // + ); + + // + Add( + PERIOD_M6, + result + // + ); + + // + Add( + PERIOD_M10, + result + // + ); + + // + Add( + PERIOD_M12, + result + // + ); + + // + Add( + PERIOD_M15, + result + // + ); + + // + Add( + PERIOD_M20, + result + // + ); + + // + Add( + PERIOD_M30, + result + // + ); + + // + Add( + PERIOD_H1, + result + // + ); + + // + Add( + PERIOD_H2, + result + // + ); + + // + Add( + PERIOD_H3, + result + // + ); + + // + Add( + PERIOD_H4, + result + // + ); + + // + Add( + PERIOD_H6, + result + // + ); + + // + Add( + PERIOD_H8, + result + // + ); + + // + Add( + PERIOD_H12, + result + // + ); + + // + Add( + PERIOD_D1, + result + // + ); + + // + Add( + PERIOD_W1, + result + // + ); + + // + Add( + PERIOD_MN1, + result + // + ); + + // + int mResult = ArraySize(result); + + // + return mResult; +} + +// +// Get Specific Time Frame Start Candle Time ... +datetime GetPeriodStartTime( + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + datetime mTime = NULL // Specified Bar Time of Host Period ... +) +{ + // + // Normalize Arg ... + mTime = NormalizeTime(mTime); + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false + // + ); + + // + datetime result = GetBarTime( + mSymbol, + mPeriod, + barIndex + // + ); + + // + return result; +} + +// +// Converts an String to it's related Market Cycle ... +ENUM_X_MARKET_CYCLES ToCycle(string value) +{ + // + ENUM_X_MARKET_CYCLES result = X_MARKET_CYCLE_UNKNOWN; + + // + ENUM_X_MARKET_CYCLES cycles[]; + int count = GetAllMarketCycles(cycles); + for (int i = 0; i < count; i++) + { + // + ENUM_X_MARKET_CYCLES iCycle = cycles[i]; + string iStr = ToString(iCycle); + + // + if (value == iStr) + { + // + result = iCycle; + break; + } + } + + // + return result; +} + +// +// Converts a Cycle to it's String Representation ... +string ToString(ENUM_X_MARKET_CYCLES cycle) +{ + // + string result = ""; + + // + string mPStr = EnumToString(cycle); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[3]; + + // + return result; +} + +// +// Retrieve all Available Cycles ... +int GetAllMarketCycles(ENUM_X_MARKET_CYCLES &result[]) +{ + // + int mResult = 0; + + // + Clean(result); + + // + ENUM_X_MARKET_CYCLES tmp[] = { + X_MARKET_CYCLE_UNKNOWN, + X_MARKET_CYCLE_SHORT, + X_MARKET_CYCLE_MEDIUM, + X_MARKET_CYCLE_LONG, + X_MARKET_CYCLE_HIND}; + + // + Copy( + tmp, + result); + + // + Clean(tmp); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Retrieve Nearest Period base on Given Period ... +ENUM_TIMEFRAMES GetNearestPeriod(ENUM_TIMEFRAMES mPeriod) +{ + // + ENUM_TIMEFRAMES result = _Period; + + // + mPeriod = NormalizePeriod(mPeriod); + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + result = PERIOD_M4; + break; + + // + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M6; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Retrieve Mediest Period base on Given Period ... +ENUM_TIMEFRAMES GetMediestPeriod(ENUM_TIMEFRAMES mPeriod) +{ + // + ENUM_TIMEFRAMES result = _Period; + + // + mPeriod = NormalizePeriod(mPeriod); + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + result = PERIOD_M15; + break; + + // + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M30; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H1; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H8; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_D1; + break; + + // + case PERIOD_H12: + result = PERIOD_W1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Retrieve Longest Period base on Given Period ... +ENUM_TIMEFRAMES GetLongestPeriod(ENUM_TIMEFRAMES mPeriod) +{ + // + ENUM_TIMEFRAMES result = _Period; + + // + mPeriod = NormalizePeriod(mPeriod); + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + result = PERIOD_M30; + break; + + // + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_H1; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H2; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H4; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H12; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_W1; + break; + + // + case PERIOD_H12: + result = PERIOD_MN1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Retrieve Hindmost Period base on Given Period ... +ENUM_TIMEFRAMES GetHindMostPeriod(ENUM_TIMEFRAMES mPeriod) +{ + // + ENUM_TIMEFRAMES result = _Period; + + // + mPeriod = NormalizePeriod(mPeriod); + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + result = PERIOD_H1; + break; + + // + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_H2; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H4; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H8; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_D1; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_MN1; + break; + + // + case PERIOD_H12: + result = PERIOD_MN1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Retrieve Specified Cycles Period related to Host Period ... +ENUM_TIMEFRAMES GetCyclePeriod( + ENUM_X_MARKET_CYCLES mCycle = NULL, // Specified Cycle + ENUM_TIMEFRAMES mPeriod = NULL // Host Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + mPeriod = NormalizePeriod(mPeriod); + mCycle = NormalizeCycle(mCycle); + + // + switch (mCycle) + { + // + // Short ... + case X_MARKET_CYCLE_SHORT: + result = GetNearestPeriod(mPeriod); + break; + + // + // Medium ... + case X_MARKET_CYCLE_MEDIUM: + result = GetMediestPeriod(mPeriod); + break; + + // + // Long ... + case X_MARKET_CYCLE_LONG: + result = GetLongestPeriod(mPeriod); + break; + + // + // Hind ... + case X_MARKET_CYCLE_HIND: + result = GetHindMostPeriod(mPeriod); + break; + } + + // + return result; +} \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.draw.lib.mq5 b/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.draw.lib.mq5 new file mode 100644 index 0000000..2bdaf10 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.draw.lib.mq5 @@ -0,0 +1,2443 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Draw Library +// -------------------------------------- +// Name: XDraw +// Description: provides Draw abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Global Definitions: Variables, Properties and etc ... + +// +// Retrieve Chart Size in Pixel ... +struct XSize +{ + long width; + long height; + + // + int x; + int y; + int w; + int h; + + // + int wStep; + int hStep; +}; + +// +// Define a Draw Specifications ... +struct XDrawSpecifications +{ + // + // Props ... + + // + bool draw; // Draw or Not ... + + // + int width; // Draw Witdth ... + color clr; // Draw Color ... + ENUM_LINE_STYLE style; // Draw Style ... + + // + bool back; // in the background + bool fill; // fill object if supported + bool selection; // highlight to move + bool rayRight; // line's continuation to the right + bool hidden; // hidden in the object list + long zOrder; // priority for mouse click + + // + string label; // Label ... + color labelColor; // Label Color ... + double labelAngel; // Label Angle ... + string labelFont; // Label Font ... + int labelFontSize; // Label Font Size ... + ENUM_ANCHOR_POINT labelAnchor; // Label Anchor Point ... + + // + // Constructor ... + XDrawSpecifications() + { + Clean(); + } + + // + // Operator ... + void operator=(const XDrawSpecifications &value) + { + // + clr = value.clr; + draw = value.draw; + width = value.width; + style = value.style; + + // + back = value.back; + hidden = value.hidden; + zOrder = value.zOrder; + rayRight = value.rayRight; + selection = value.selection; + + // + fill = value.fill; + + // + label = value.label; + labelColor = value.labelColor; + labelAngel = value.labelAngel; + labelFont = value.labelFont; + labelFontSize = value.labelFontSize; + labelAnchor = value.labelAnchor; + } + + // + // Functions ... + + // + void Clean() + { + // + draw = false; + width = 1; + clr = CLR_NONE; + style = STYLE_SOLID; + + // + back = false; + hidden = false; + rayRight = false; + selection = false; + fill = false; + + // + zOrder = 0; + + // + label = ""; + labelColor = CLR_NONE; + labelAngel = 0; + labelFont = "Arial"; + labelFontSize = 20; + labelAnchor = ANCHOR_LEFT_UPPER; + } + + // + void Label( + string mLabel = "", // Label ... + color mLabelColor = CLR_NONE, // Label Color ... + string mLabelFont = "Arial", // Label Font ... + int mLabelFontSize = 20, // Label Font Size ... + ENUM_ANCHOR_POINT mLabelAnchor = ANCHOR_LEFT_UPPER, // Label Anchor Point ... + double mLabelAngel = 0 // Label Angle ... + ) + { + // + label = mLabel; + labelFont = mLabelFont; + labelColor = mLabelColor; + labelAngel = mLabelAngel; + labelAnchor = mLabelAnchor; + labelFontSize = mLabelFontSize; + } +}; + +// +// Candle Draw Specifications ... +struct XOHCLDrawSpecification +{ + // + // Props ... + XDrawSpecifications openStyle; + XDrawSpecifications highStyle; + XDrawSpecifications closeStyle; + XDrawSpecifications lowStyle; + + // + // Constructors ... + XOHCLDrawSpecification() + { + Clean(); + } + + // + // Operators ... + void operator=(const XOHCLDrawSpecification &value) + { + // + lowStyle = value.lowStyle; + openStyle = value.openStyle; + highStyle = value.highStyle; + closeStyle = value.closeStyle; + } + + // + // Functions ... + + // + void Clean() + { + // + lowStyle.Clean(); + openStyle.Clean(); + highStyle.Clean(); + closeStyle.Clean(); + } + + // + void Default() + { + // + // Open ... + openStyle.width = 1; + openStyle.draw = true; + openStyle.clr = clrLime; + openStyle.style = STYLE_SOLID; + openStyle.Label( + "O", + openStyle.clr); + + // + // High ... + highStyle.width = 1; + highStyle.draw = true; + highStyle.clr = clrAqua; + highStyle.style = STYLE_SOLID; + highStyle.Label( + "H", + highStyle.clr); + + // + // Close ... + closeStyle.width = 1; + closeStyle.draw = true; + closeStyle.clr = clrRed; + closeStyle.style = STYLE_SOLID; + closeStyle.Label( + "C", + closeStyle.clr); + + // + // Low ... + lowStyle.width = 1; + lowStyle.draw = true; + lowStyle.clr = clrMagenta; + lowStyle.style = STYLE_SOLID; + lowStyle.Label( + "L", + lowStyle.clr); + } + + // + void Width(int value) + { + // + lowStyle.width = value; + openStyle.width = value; + highStyle.width = value; + closeStyle.width = value; + } + + // + void Style(ENUM_LINE_STYLE value) + { + // + lowStyle.style = value; + openStyle.style = value; + highStyle.style = value; + closeStyle.style = value; + } + + // + void Color(color value) + { + // + lowStyle.clr = value; + openStyle.clr = value; + highStyle.clr = value; + closeStyle.clr = value; + } + + // + void RayRight(bool value) + { + // + lowStyle.rayRight = value; + openStyle.rayRight = value; + highStyle.rayRight = value; + closeStyle.rayRight = value; + } + + // + void Draw(bool value) + { + // + lowStyle.draw = value; + openStyle.draw = value; + highStyle.draw = value; + closeStyle.draw = value; + } + + // + void Back(bool value) + { + // + lowStyle.back = value; + openStyle.back = value; + highStyle.back = value; + closeStyle.back = value; + } + + // + void Fill(bool value) + { + // + lowStyle.fill = value; + openStyle.fill = value; + highStyle.fill = value; + closeStyle.fill = value; + } + + // + void Label(string value) + { + // + lowStyle.Label(value); + openStyle.Label(value); + highStyle.Label(value); + closeStyle.Label(value); + } + + // + void SetLabelPrefix(string value) + { + // + lowStyle.label = value + " " + lowStyle.label; + openStyle.label = value + " " + openStyle.label; + highStyle.label = value + " " + highStyle.label; + closeStyle.label = value + " " + closeStyle.label; + } +}; + +// +string drawPrefix = "X-OBJ"; + +// +// Common Draw Functions ... + +// +// remove drawn objects ... +void RemoveDraws( + string tag = NULL, + long chartId = -1, + int subWindow = -1 // +) +{ + // + // Normalize Args ... + // + if (tag == NULL) + { + tag = drawPrefix; + } + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, tag) >= 0) + { + ObjectDelete(chartId, on); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + +// +bool RemoveDraw( + string name, + long chartId = -1, + int subWindow = -1 // +) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + string objName = ""; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, name) >= 0) + { + // + objName = on; + break; + } + } + + // + if (StringLen(objName) > 0) + { + result = ObjectDelete(chartId, objName); + } + + // + return result; +} + +// +// Deselect All Draws ... +void DeselectAllDraws() +{ + // + int objs = ObjectsTotal(ChartID(), 0); + for (int o = 0; o < objs; o++) + { + ObjectSetInteger(ChartID(), ObjectName(ChartID(), o, 0), OBJPROP_SELECTED, false); + } + + // + ChartRedraw(); +} + +// +// Check Object Exists ... +bool IsDrawExists( + string name, + long chartId = -1, + int subWindow = -1 // +) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + result = StringFind(on, name) >= 0; + if (result) + { + break; + } + } + + // + return result; +} + +// +// Regular Draws ... + +// +// Arrow Functions ... + +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = 252, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) +{ + // + bool result = false; + + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create an arrow ... + result = ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price); + if (!result) + { + return result; + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return result; +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + bool result = false; + + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // move the anchor point ... + result = ObjectMove(chartID, name, 0, time, price); + + // + return result; +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) +{ + // + bool result = false; + + // + // delete an arrow ... + result = !ObjectDelete(chartID, name); + + // + return result; +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) +{ + // + bool result = false; + + // + // change the arrow code ... + result = ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code); + + // + return result; +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) +{ + // + bool result = false; + + // + // change anchor type ... + result = !ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor); + + // + return result; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price // +) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} + +// +// Horizontal Line Functions ... + +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // if the price is not set, set it at the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a horizontal line ... + result = ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price); + if (!result) + { + return result; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return result; +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) +{ + // + bool result = false; + + // + // if the line price is not set, move it to the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // move a horizontal line ... + result = ObjectMove(chartID, name, 0, 0, price); + + // + return result; +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) +{ + // + bool result = false; + + // + // delete a horizontal line ... + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Vertical Line Functions ... + +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int subWindow = 0, // subwindow index + datetime time = 0, // line time + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // if the line time is not set, draw it via the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a vertical line ... + result = ObjectCreate(chartID, objName, OBJ_VLINE, subWindow, time, 0); + if (!result) + { + return result; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return result; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) +{ + // + bool result = false; + + // + // if line time is not set, move the line to the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // move the vertical line ... + result = ObjectMove(chartID, name, 0, time, 0); + + // + return result; +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) +{ + // + bool result = false; + + // + // delete the vertical line ... + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Rectangle Functions ... + +// +// Create rectangle by the given coordinates ... +bool DrawRectangle( + const long chartID = 0, // chart's ID + const string name = "Rectangle", // rectangle name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // rectangle color + const ENUM_LINE_STYLE style = STYLE_SOLID, // style of rectangle lines + const int width = 1, // width of rectangle lines + const bool fill = false, // filling rectangle with color + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // Set anchor points' coordinates if they are not set ... + ChangeRectangleEmptyPoints(time1, price1, time2, price2); + + // + // Create a rectangle by the given coordinates ... + result = ObjectCreate(chartID, name, OBJ_RECTANGLE, subWindow, time1, price1, time2, price2); + if (!result) + { + return result; + } + + // + // Set rectangle color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // Set the style of rectangle lines + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // Set width of the rectangle lines ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // Enable (true) or disable (false) the mode of filling the rectangle ... + ObjectSetInteger(chartID, name, OBJPROP_FILL, fill); + + // + // Display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // Enable (true) or disable (false) the mode of highlighting the rectangle for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + + // + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // Hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // Set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // Successful execution + return result; +} + +// +// Move the rectangle anchor point ...s +bool RectanglePointChange( + const long chartID = 0, // chart's ID + const string name = "Rectangle", // rectangle name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + bool result = false; + + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // Move the anchor point ... + result = ObjectMove(chartID, name, pointIndex, time, price); + + // + return result; +} + +// +// Delete the rectangle ... +bool DeleteRectangle( + const long chartID = 0, // chart's ID + const string name = "Rectangle" // rectangle name +) +{ + // + bool result = false; + + // + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Check the values of rectangle's anchor points and set default +// values for empty ones +void ChangeRectangleEmptyPoints( + datetime &time1, double &price1, + datetime &time2, double &price2 // +) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, move it 300 points lower than the first one ... + if (!price2) + { + price2 = price1 - 300 * SymbolInfoDouble(Symbol(), SYMBOL_POINT); + } +} + +// +// RectangleLabel Functions ... + +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color bgColor = clrWhiteSmoke, // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a rectangle label + result = ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0); + if (!result) + { + return result; + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, bgColor); + + // + // set border type ... + ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the label by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return result; +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + bool result = false; + + // + // move the rectangle label ... + result = ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + return result; +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) +{ + // + bool result = false; + + // + // delete the label ... + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) +{ + // + bool result = false; + + // + // change label size ... + result = ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + return result; +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) +{ + // + bool result = false; + + // + // change border type ... + result = ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border); + + // + return result; +} + +// +// TrendLine Funcions ... + +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a trend line by the given coordinates ... + result = ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2); + if (!result) + { + return result; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return result; +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + bool result = false; + + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // move trend line's anchor point ... + result = ObjectMove(chartID, name, pointindex, time, price); + + // + return result; +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) +{ + // + bool result = false; + + // + // delete a trend line ... + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2 // +) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) + { + price2 = price1; + } +} + +// +// Text Functions ... + +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time, price); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // + // create Text object + result = ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price); + if (!result) + { + return result; + } + + // + // set the text ... + ObjectSetString(chartID, objName, OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, objName, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the object by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return result; +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + bool result = false; + + // + // + // if point position is not set, move it to the current bar having Bid price + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // move the anchor point ... + result = ObjectMove(chartID, name, 0, time, price); + + // + return result; +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) +{ + // + bool result = false; + + // + // change object text ... + result = ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + return result; +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) +{ + // + bool result = false; + + // + // delete the object ... + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price // +) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} + +// +// Fibonacchi Functions ... + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + result = ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2); + if (!result) + { + return result; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return result; +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + result = ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2); + if (!result) + { + return result; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + objName); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + bool result = false; + + // + // check array sizes ... + result = levels == ArraySize(colors) && + levels == ArraySize(styles) && + levels == ArraySize(widths) && + levels == ArraySize(widths); + if (!result) + { + return result; + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for (int i = 0; i < levels; i++) + { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return result; +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + bool result = false; + + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // move the anchor point ... + result = ObjectMove(chartID, name, pointIndex, time, price); + + // + return result; +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + bool result = false; + + // + // delete the object ... + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2 // +) +{ + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) + { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) + { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time2, 10, temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) + { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} + +// +// Event Functions ... + +// +// Create an Event ... +bool EventCreate( + const long chartID = 0, // chart's ID + const string name = "Event", // object name + const int subWindow = 0, // subwindow index + const string text = "Content", // event text + datetime time = 0, // anchor point time + const color clr = clrRed, // color + const int width = 1, // point width when highlighted + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + if (!time) + { + time = TimeCurrent(); + } + + // + result = ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0); + if (!result) + { + return result; + } + + // + // set event text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set anchor point width if the object is highlighted + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving event by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution + return result; +} + +// +// Change Event object text +bool EventTextChange( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + const string text = "Content" // text +) +{ + // + bool result = false; + + // + // change object text + result = ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + return result; +} + +// +// Move Event object +bool EventMove( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + datetime time = 0 // time +) +{ + // + bool result = false; + + // + // if time is not set, move event to the last bar + if (!time) + { + time = TimeCurrent(); + } + + // + // move the object + result = ObjectMove(chartID, name, 0, time, 0); + + // + return result; +} + +// +// Delete Event object +bool EventDelete( + const long chartID = 0, // chart's ID + const string name = "Event" // event name +) +{ + // + bool result = false; + + // + // delete the object + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Button Functions ... + +// +// Create the button ... +bool ButtonCreate( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // button width + const int height = 15, // button height + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const string text = "Button", // text + const string font = "Arial", // font + const int fontSize = 8, // font size + const color clr = clrBlack, // text color + const color bgColor = clrLightGray, // background color + const color borderColor = clrNONE, // border color + const bool state = false, // pressed/released + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // create the button + result = ObjectCreate(chartID, name, OBJ_BUTTON, subWindow, 0, 0); + if (!result) + { + return result; + } + + // + // set button coordinates + ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + // set button size + ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + // set the chart's corner, relative to which point coordinates are defined + ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + // set the text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set text font + ObjectSetString(chartID, name, OBJPROP_FONT, font); + + // + // set font size + ObjectSetInteger(chartID, name, OBJPROP_FONTSIZE, fontSize); + + // + // set text color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set background color + ObjectSetInteger(chartID, name, OBJPROP_BGCOLOR, bgColor); + + // + // set border color + ObjectSetInteger(chartID, name, OBJPROP_BORDER_COLOR, borderColor); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // set button state + ObjectSetInteger(chartID, name, OBJPROP_STATE, state); + + // + // enable true or disable false the mode of moving the button by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + return result; +} + +// +// Move the button ... +bool ButtonMove( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + bool result = false; + + // + // move the button + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + return result; +} + +// +// Change button size ... +bool ButtonChangeSize( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int width = 50, // button width + const int height = 18 // button height +) +{ + // + bool result = false; + + // + // change the button size + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + return result; +} + +// +// Change corner of the chart for binding the button ... +bool ButtonChangeCorner( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER // chart corner for anchoring +) +{ + // + bool result = false; + + // + // change anchor corner + result = ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + return result; +} + +// +// Change button text ... +bool ButtonTextChange( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const string text = "Text" // text +) +{ + // + bool result = false; + + // + // change object text + result = ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + return result; +} + +// +// Delete the button ... +bool ButtonDelete( + const long chartID = 0, // chart's ID + const string name = "Button" // button name +) +{ + // + bool result = false; + + // + // delete the button + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Chart Style Drawers ... + +// +// Apply Styles On Chart ... +void ApplyChartStyle( + long mChartId = -1, // chart's ID + ENUM_CHART_MODE mMode = CHART_CANDLES, // chart's mMode + bool mShowBidLine = true, // show bid line + bool mShowAskLine = true, // show ask line + bool mShowGrid = false, // show grids on chart + bool mShowVolumes = false, // show volumes + bool mShowTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true, // chart autoscroll + bool mQuickNavigation = true, // chart quick navigation state + color mForeGroundColor = clrWhite, // chart's foreground color + color mBackGroundColor = clrBlack, // chart's background color + color mUpColor = clrGreen, // Up Color + color mDownColor = clrRed, // Down Color + color mBullishColor = clrGreen, // Bullish color + color mBearishColor = clrRed, // Bearish color + color mGridColor = clrGray, // grid color + color mBidLineColor = clrGray, // bid line color + color mAskLineColor = clrRed, // ask line color + color mLineColor = clrLime, // line mMode and doji candlestick color + color mStopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (mChartId == -1) + { + mChartId = 0; + } + + // + ChartSetInteger(mChartId, CHART_MODE, mMode); + ChartSetInteger(mChartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(mChartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(mChartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(mChartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(mChartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(mChartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(mChartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(mChartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(mChartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(mChartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(mChartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(mChartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(mChartId, CHART_COLOR_VOLUME, mVolumesColor); +} + +// +// Tools ... + +// +// Retrieve Chart Size ... +bool GetChartSize( + XSize &result, // Holds Result ... + long chartID = 0 // Specified Chart ID ... +) +{ + // + bool mResult = false; + + // + mResult = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0, result.width); + if (!mResult) + { + return mResult; + } + + // + mResult = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0, result.height); + + // + return mResult; +} diff --git a/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.xtrade.lib.mq5 b/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.xtrade.lib.mq5 new file mode 100644 index 0000000..7249f50 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/Libraries/x-saherelm.xtrade.lib.mq5 @@ -0,0 +1,4167 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XTradeLib +// Description: All models related to Trade ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xdata-collector.class.mq5" + +// +// Definitions ... + +// +// a List of Used Tokens ... + +// +// Common ... +string XIDToken = "ID"; +string XTicketToken = "TK"; +string XModeToken = "MD"; +string XTypeToken = "TY"; +string XPeriodToken = "PR"; +string XProviderToken = "PRV"; +string XProfitToken = "PF"; + +// +string XTPToken = "TP"; +string XSLToken = "SL"; +string XTimeToken = "TM"; +string XEntryToken = "EN"; +string XVolumeToken = "VL"; +string XSymbolToken = "SMBL"; + +// +string XSupportToken = "SP"; +string XEQMSupportToken = "EQM"; + +// +string XSLTrailToken = "SLT"; + +// +string XActionToken = "A"; + +// +// Available Order Modes ... +enum ENUM_X_ORDER_MODES +{ + X_ORDER_MODE_NOTHING, // Nothing + X_ORDER_MODE_MARKET, // Market Order + X_ORDER_MODE_STOP, // Pending Stop Order + X_ORDER_MODE_LIMIT, // Pending Limit Order + X_ORDER_MODE_STOP_LIMIT, // Pending Stop Limit Order +}; + +// +// Select Positions Type ... +enum ENUM_X_POSITION_SELECT_METHODS +{ + X_POSITION_SELECT_NONE, // None + X_POSITION_SELECT_MAX, // Max + X_POSITION_SELECT_MIN, // Min + X_POSITION_SELECT_BOTH, // Min and Max + X_POSITION_SELECT_ALL, // All +}; + +// +// Signal Execution Result ... +// note that some of them must be handles in +// EA's ... +enum ENUM_X_SIGNAL_EXECUTION_RESULT +{ + // + X_SIGNAL_EXECUTION_UNKNOWN, // Unknown + X_SIGNAL_EXECUTION_SUCCEED, // Succed + X_SIGNAL_EXECUTION_FAILED_SPREAD, // Spread more than Max Allowed + X_SIGNAL_EXECUTION_FAILED_NO_EQUITY, // No Equity for Trade + X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR, // Price Error + X_SIGNAL_EXECUTION_FAILED_MAX_REACHED, // Max Allowed Positions Reached + X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS, // Invalid Params +}; + +// +// How to Manage Signal TP and SL ... +enum ENUM_X_SIGNAL_MANAGING_ACTIONS +{ + // + X_SIGNAL_USE_NOTHING, // Use 0 index if exists and ignore if not + X_SIGNAL_USE_MAX, // Use Max Value + X_SIGNAL_USE_MIN, // Use Min Value + X_SIGNAL_PARTIAL_CLOSE, // Use Max as Regular but Partial Close at each Step + X_SIGNAL_TRAIL, // Use 0 index as SL and Trail Stop on TP Levels + X_SIGNAL_PARTIAL_TRAIL, // Use 0 index as SL and Trail Stop on TP Levels and also Partial Close on TP Levels +}; + +// +// Available Guard Action ... +enum ENUM_X_GUARD_ACTIONS +{ + X_GUARD_ACTION_NOTHING, // Nothing + X_GUARD_ACTION_HEDGE, // Hedge + X_GUARD_PARTIAL_CLOSE, // Partial Close + X_GUARD_ACTION_TRAIL_STOP, // Trail StopLoss + X_GUARD_ACTION_FORCE_CLOSE, // Force Close + X_GUARD_ACTION_ADD_SUPPORT_SIGNAL, // Add Support Signal + X_GUARD_ACTION_CANCEL_PENDING_ORDERS, // Cancel Pending Orders +}; + +// +// Structs ... + +// +// Model a Signal ... +struct XSignal +{ + // + // Props ... + + // + ulong positionId; // if Executed this filled ... + double entry; // Exntry or Execution Price ... + double volume; // Position Volume ... + + // + datetime time; // Issue Time ... + + // + ENUM_X_SIGNAL_MANAGING_ACTIONS action; // Signal Managing Action ... + + double tps[]; // a Collection of TP(s) ... + double sls[]; // a Collection of SL(s) ... + + // + string symbol; // Trading Symbol ... + string provider; // Signaller ... + string comment; // Comment ... + + // + ENUM_TIMEFRAMES period; // Trading TimeFrame ... + ENUM_POSITION_TYPE type; // Long (Buy) or Short (Sell) ... + ENUM_X_ORDER_MODES mode; // Execution Mode ... + + // + XSignal supports[]; // a Collecion of Support Signals ... + XOHCLSupRes supportResistances; // Support and Resistances ... + + // + // Constructor ... + XSignal() + { + Clean(); + } + + // + // DO All Calculations and Normalizations ... + bool Normalize() + { + // + bool result = false; + + // + // Normalizations ... + symbol = NormalizeSymbol(symbol); + period = NormalizePeriod(period); + + // + entry = NormalizePrice(entry, symbol); + volume = NormalizeVolume(volume, symbol); + + // + time = NormalizeTime(time); + + // + int slsCount = ArraySize(sls); + if (slsCount > 0) + { + // + for (int i = 0; i < slsCount; i++) + { + sls[i] = NormalizePrice(sls[i], symbol); + } + } + + // + int tpsCount = ArraySize(tps); + if (tpsCount > 0) + { + // + for (int i = 0; i < tpsCount; i++) + { + tps[i] = NormalizePrice(tps[i], symbol); + } + } + + // + result = IsValid(); + + // + return result; + } + + // + bool Prepare( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell) + ENUM_X_ORDER_MODES mMode, // Execution Mode + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + bool result = false; + + // + result = + // + IsValid(mMode) && + IsValid(mSymbol) && + IsValid(mPeriod) && + NotEmpty(mEntry) && + NotEmpty(mVolume) && + IsValid(mProvider) + // + ; + if (!result) + { + return result; + } + + // + if (tp < 0) + { + tp = 0; + } + + // + if (sl < 0) + { + sl = 0; + } + + // + if (tp == 0 && sl == 0) + { + action = X_SIGNAL_USE_NOTHING; + } + + // + type = mType; + mode = mMode; + symbol = mSymbol; + period = mPeriod; + provider = mProvider; + + // + // Normalization Values ... + sl = NormalizePrice(sl, mSymbol); + tp = NormalizePrice(tp, mSymbol); + mEntry = NormalizePrice(mEntry, mSymbol); + mVolume = NormalizeVolume(mVolume, mSymbol); + + // + entry = mEntry; + volume = mVolume; + + // + action = mAction; + + // + Add( + sl, + sls + // + ); + + // + Add( + tp, + tps + // + ); + + // + result = Normalize(); + + // + return result; + } + + // + bool PrepareLong( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + ENUM_X_ORDER_MODES mMode, // Execution Mode + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return Prepare( + mSymbol, + mProvider, + mPeriod, + POSITION_TYPE_BUY, + mMode, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + bool PrepareShort( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + ENUM_X_ORDER_MODES mMode, // Execution Mode + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return Prepare( + mSymbol, + mProvider, + mPeriod, + POSITION_TYPE_SELL, + mMode, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + // Market Mode ... + + // + bool PrepareMarketLong( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return PrepareLong( + mSymbol, + mProvider, + mPeriod, + X_ORDER_MODE_MARKET, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + bool PrepareMarketShort( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return PrepareShort( + mSymbol, + mProvider, + mPeriod, + X_ORDER_MODE_MARKET, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + // Stop Mode ... + + // + bool PrepareStopLong( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return PrepareLong( + mSymbol, + mProvider, + mPeriod, + X_ORDER_MODE_STOP, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + bool PrepareStopShort( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return PrepareShort( + mSymbol, + mProvider, + mPeriod, + X_ORDER_MODE_STOP, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + // Limit Mode ... + + // + bool PrepareLimitLong( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return PrepareLong( + mSymbol, + mProvider, + mPeriod, + X_ORDER_MODE_LIMIT, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + bool PrepareLimitShort( + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit + ) + { + // + return PrepareShort( + mSymbol, + mProvider, + mPeriod, + X_ORDER_MODE_LIMIT, + mEntry, + mVolume, + mAction, + sl, + tp + // + ); + } + + // + // here we Can Modify TP and SL and also Action ... + bool Modify( + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction, + double &mTps[], + double &mSls[] + // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + // Only Position Manager works on Market Execution Positions ... + if (mAction != X_SIGNAL_USE_NOTHING && + mode != X_ORDER_MODE_MARKET) + { + return result; + } + + // + int mTpsCount = ArraySize(mTps); + int mSlsCount = ArraySize(mSls); + + // + if (mAction != X_SIGNAL_USE_NOTHING) + { + // + if (mAction == X_SIGNAL_USE_MAX || + mAction == X_SIGNAL_USE_MIN || + mAction == X_SIGNAL_PARTIAL_TRAIL) + { + result = mTpsCount > 0 || mSlsCount > 0; + } + else + { + result = mTpsCount > 0 && mSlsCount > 0; + } + } + + // + if (result) + { + // + double defaultValue = 0; + + // + Copy( + mTps, + tps + // + ); + if (ArraySize(tps) <= 0) + { + // + Add( + defaultValue, + tps + // + ); + } + + // + Copy( + mSls, + sls + // + ); + if (ArraySize(sls) <= 0) + { + // + Add( + defaultValue, + sls + // + ); + } + + // + action = mAction; + + // + result = IsValid(); + } + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + entry = 0; + volume = 0; + positionId = 0; + + // + time = NULL; + type = NULL; + mode = NULL; + symbol = NULL; + period = NULL; + comment = NULL; + provider = NULL; + + // + Clean(tps); + Clean(sls); + Clean(supports); + supportResistances.Clean(); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(period) && + IsValid(symbol) && + NotEmpty(volume) && + NotEmpty(entry) && + (ArraySize(tps) > 0 || + ArraySize(sls) > 0) + // + ; + + // + if (!result) + { + return result; + } + + // + // Validate Actions ... + + // + // Only Position Manager works on Market Execution Positions ... + result = + // + !(action != X_SIGNAL_USE_NOTHING && + mode != X_ORDER_MODE_MARKET) + // + ; + if (!result) + { + return result; + } + + // + int tpsCount = ArraySize(tps); + int slsCount = ArraySize(sls); + + // + if (action != X_SIGNAL_USE_NOTHING) + { + // + if (action == X_SIGNAL_USE_MAX || + action == X_SIGNAL_USE_MIN || + action == X_SIGNAL_PARTIAL_TRAIL) + { + result = tpsCount > 0 || slsCount > 0; + } + else + { + result = tpsCount > 0 && slsCount > 0; + } + } + + // + return result; + } + + // + // Check Signal Executed or not ... + bool IsExecuted() + { + // + bool result = false; + + // + result = + // + IsValid() && + NotEmpty(positionId) + // + ; + + // + return result; + } + + // + // Generate Comment for Signal ... + string GenerateComment() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + if (IsValid(provider)) + { + // + // Generate Provider Tag ... + result += GenerateProviderTag(provider); + } + + // + if (IsValid(period)) + { + // + // Generate Period Tag ... + result += GeneratePeriodTag(period); + } + + // + return result; + } + + // + // Check this instance is Same os Given instance or not ... + bool IsSameAs( + const XSignal &value // instance for Compare + ) + { + // + bool result = false; + + // + result = + // + type == value.type && + mode == value.mode && + entry == value.entry && + volume == value.volume && + symbol == value.symbol && + provider == value.provider && + positionId == value.positionId && + ArraySize(sls) == ArraySize(value.sls) && + ArraySize(tps) == ArraySize(value.tps) + // + ; + + // + return result; + } + + // + // Find index in a Collection ... + int FindIndex( + const XSignal &values[] // Collection to Find + ) + { + // + return FindIndex( + this, + values + // + ); + } + + // + // Check Items Passed Specific Filters or not ... + bool IsFiltersPassed( + string mSymbol = NULL, // Trading Symbol + string mProvider = NULL, // Signal Provider + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe + ENUM_POSITION_TYPE mType = NULL, // Long (Buy), Short (Sell) + ENUM_X_ORDER_MODES mMode = NULL // Execution Mode + ) + { + // + bool result = false; + + // + result = + // + // Symbol Filter ... + IsSymbolFilterPassed( + mSymbol, + this + // + ) + // + && + // + // Provider Filter ... + IsProviderFilterPassed( + mProvider, + this + // + ) + // + && + // + // Period Filter ... + IsPeriodFilterPassed( + mPeriod, + this + // + ) + // + && + // + // Type Filter ... + IsTypeFilterPassed( + mType, + this + // + ) + // + && + // + // Mode Filter ... + IsModeFilterPassed( + mMode, + this + // + ) + // + ; + + // + return result; + } + + // + string GetToken() + { + return GetToken(this); + } + + // + bool IsModelValid() + { + return IsValid(); + } + + // + // To String Representation ... + string ToModelString() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + // For Modeling a Signal we Only Used: + // - Period; + // - Provider; + // - Type; + // - Mode; + // - Symbol; + // - PositionID; + // - Entry; + // - Volume; + // - TPS; + // - SLS; + // - Issue Time; + + // + int iPeriodInt = (int)period; + + // + string periodStr = Surround(XPeriodToken, iPeriodInt); + string providerStr = Surround(XProviderToken, provider); + string typeStr = Surround(XTypeToken, type); + string modeStr = Surround(XModeToken, mode); + string SymbolStr = Surround(XSymbolToken, symbol); + string positionIdStr = Surround(XIDToken, positionId); + string entryStr = Surround(XEntryToken, entry); + string volumeStr = Surround(XVolumeToken, volume); + string timeStr = Surround(XTimeToken, time); + + // + string actionStr = Surround(XActionToken, action); + + // + // TP ... + string tpsContentStr = ToString(tps); + string tpsStr = Surround(XTPToken, tpsContentStr); + + // + // SL ... + string slsContentStr = ToString(sls); + string slsStr = Surround(XSLToken, slsContentStr); + + // + result = + // + GetToken() + + "[" + + // + periodStr + + providerStr + + typeStr + + modeStr + + SymbolStr + + positionIdStr + + entryStr + + volumeStr + + actionStr + + tpsStr + + slsStr + + timeStr + + // + "]" + // + ; + + // + return result; + } + + // + // Parse String Model and Fill Available + // Items ... + bool ParseModel(string value) + { + // + bool result = false; + + // + Clean(); + + // + if (!IsValid(value)) + { + return false; + } + + // + // For Modeling a Signal we Only Used: + // - Period; + // - Provider; + // - Type; + // - Mode; + // - Symbol; + // - PositionID; + // - Entry; + // - Volume; + // - TPS; + // - SLS; + // - Issue Time; + + // + entry = ParseDoubleSurrounded(value, XEntryToken); + volume = ParseDoubleSurrounded(value, XVolumeToken); + positionId = ParseLongSurrounded(value, XIDToken); + + // + time = ParseTimeSurrounded(value, XTimeToken); + symbol = ParseStringSurrounded(value, XSymbolToken); + provider = ParseStringSurrounded(value, XProviderToken); + type = ((ENUM_POSITION_TYPE)ParseIntSurrounded(value, XTypeToken)); + mode = ((ENUM_X_ORDER_MODES)ParseIntSurrounded(value, XModeToken)); + period = ((ENUM_TIMEFRAMES)ParseIntSurrounded(value, XPeriodToken)); + + // + action = ((ENUM_X_SIGNAL_MANAGING_ACTIONS)ParseIntSurrounded(value, XActionToken)); + + // + // TPS ... + ParseDoubleArraySurrounded( + tps, + value, + XTPToken + // + ); + + // + // SLS ... + ParseDoubleArraySurrounded( + sls, + value, + XSLToken + // + ); + + // + // Validate ... + result = IsValid(); + ; + + // + return result; + } + + // + // Select Regular SL ... + bool RegularSL(double &sl) + { + // + bool result = false; + + // + sl = 0; + int slsCount = ArraySize(sls); + + // + result = IsValid() && slsCount > 0; + if (!result) + { + return result; + } + + // + if ( + action == X_SIGNAL_TRAIL || + action == X_SIGNAL_USE_NOTHING || + action == X_SIGNAL_PARTIAL_TRAIL) + { + sl = sls[0]; + } + else if (action == X_SIGNAL_USE_MAX || + action == X_SIGNAL_PARTIAL_CLOSE) + { + sl = GetMin(sls); + } + else if (action == X_SIGNAL_USE_MIN) + { + sl = GetMax(sls); + } + + // + return result; + } + + // + // Select Regular TP ... + bool RegularTP(double &tp) + { + // + bool result = false; + + // + tp = 0; + int tpsCount = ArraySize(tps); + + // + result = IsValid() && tpsCount > 0; + if (!result) + { + return result; + } + + // + if ( + action == X_SIGNAL_TRAIL || + action == X_SIGNAL_USE_NOTHING || + action == X_SIGNAL_PARTIAL_TRAIL) + { + tp = tps[0]; + } + else if (action == X_SIGNAL_USE_MAX || + action == X_SIGNAL_PARTIAL_CLOSE) + { + tp = GetMax(tps); + } + else if (action == X_SIGNAL_USE_MIN) + { + tp = GetMin(tps); + } + + // + return result; + } + + // + // Retrieve Entry Price ... + double GetEntry() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetEntry( + symbol, + type + // + ); + + // + return result; + } + + // + // Retrieve Exit ... + double GetExit() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetExit( + symbol, + type + // + ); + + // + return result; + } + + // + // Get Spread by Point ... + double GetSpread() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = PriceToPoint(GetSpread(symbol)); + + // + return result; + } +}; + +// +// Model an Open Position ... +struct XPosition +{ + // + // Props ... + + // + // Magic Number ... + ulong magic; + + // + // Ticket ID ... + ulong ticket; + + // + // Tradinng Symbol ... + string symbol; + + // + // Trading Period ... + ENUM_TIMEFRAMES period; + + // + // Position Type ... + ENUM_POSITION_TYPE type; + + // + // Take Profit ... + double tp; + + // + // Stop Loss ... + double sl; + + // + // Position Current Profit ... + double profit; + + // + // Position Open Price ... + double entry; + + // + // Current Symbol Price ... + double price; + + // + // Position Swap ... + double swap; + + // + // Position Commission ... + double commission; + + // + // Volume ... + double volume; + + // + // Position Open Time ... + datetime openAt; + + // + // Sifnal Provider ... + string provider; + + // + // Position Comment ... + string comment; + + // + // Constructor ... + XPosition() + { + Clean(); + } + + // + // Initializers ... + + bool ByIndex(int index) + { + // + bool result = false; + + // + static CPositionInfo mPositionInfo; + + // + result = mPositionInfo.SelectByIndex(index); + if (!result) + { + return result; + } + + // + ulong mTicket = mPositionInfo.Ticket(); + + // + result = ByTicket(mTicket); + + // + return result; + } + + bool ByTicket(ulong mTicket) + { + // + bool result = false; + + // + static CPositionInfo mPositionInfo; + + // + result = mPositionInfo.SelectByTicket(mTicket); + if (!result) + { + return result; + } + + // + swap = mPositionInfo.Swap(); + magic = mPositionInfo.Magic(); + openAt = mPositionInfo.Time(); + sl = mPositionInfo.StopLoss(); + ticket = mPositionInfo.Ticket(); + symbol = mPositionInfo.Symbol(); + tp = mPositionInfo.TakeProfit(); + profit = mPositionInfo.Profit(); + volume = mPositionInfo.Volume(); + comment = mPositionInfo.Comment(); + entry = mPositionInfo.PriceOpen(); + type = mPositionInfo.PositionType(); + price = mPositionInfo.PriceCurrent(); + commission = mPositionInfo.Commission(); + + // + period = ExtractPeriod(comment); + provider = ExtractProvider(comment); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + magic = 0; + ticket = 0; + tp = 0; + sl = 0; + swap = 0; + entry = 0; + price = 0; + profit = 0; + volume = 0; + openAt = 0; + commission = 0; + + // + type = NULL; + period = NULL; + + // + symbol = NULL; + comment = NULL; + provider = NULL; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + NotEmpty(ticket) + // + ; + + // + return result; + } + + // + // Retrieve Entry Price ... + double GetEntry() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetEntry( + symbol, + type + // + ); + + // + return result; + } + + // + // Retrieve Exit ... + double GetExit() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetExit( + symbol, + type + // + ); + + // + return result; + } + + // + // Get Spread by Point ... + double GetSpread() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = PriceToPoint(GetSpread(symbol)); + + // + return result; + } + + // + // Calculate Age ... + int GetAge( + ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period + ) + { + return GetAge(this, mPeriod); + } + + // + // Check this instance is Same os Given instance or not ... + bool IsSameAs( + const XPosition &value // instance for Compare + ) + { + // + bool result = false; + + // + result = + // + type == value.type && + magic == value.magic && + entry == value.entry && + ticket == value.ticket && + volume == value.volume && + symbol == value.symbol && + provider == value.provider + // + ; + + // + return result; + } + + // + // Find index in a Collection ... + int FindIndex( + const XPosition &values[] // Collection to Find + ) + { + // + return FindIndex( + this, + values + // + ); + } + + // + // Check Items Passed Specific Filters or not ... + bool IsFiltersPassed( + string mSymbol = NULL, // Trading Symbol + string mProvider = NULL, // Signal Provider + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe + ENUM_POSITION_TYPE mType = NULL, // Long (Buy), Short (Sell) + ulong mMagic = NULL, // Magic Number + bool mFilterByMagic = true // Get Only Self Open Positions + ) + { + // + bool result = false; + + // + result = + // + // Magic Filter ... + IsMagicFilterPassed( + mMagic, + mFilterByMagic, + this + // + ) + // + && + // + // Symbol Filter ... + IsSymbolFilterPassed( + mSymbol, + this + // + ) + // + && + // + // Provider Filter ... + IsProviderFilterPassed( + mProvider, + this + // + ) + // + && + // + // Period Filter ... + IsPeriodFilterPassed( + mPeriod, + this + // + ) + // + && + // + // Type Filter ... + IsTypeFilterPassed( + mType, + this + // + ) + // + ; + + // + return result; + } +}; + +// +// Model an Order ... +struct XOrder +{ + // + // Time of order placement ... + datetime setupAt; + + // + // Time of order expiration ... + datetime expiredAt; + + // + // Time of order execution or cancellation ... + datetime executedAt; + + // + // Order type ... + ENUM_ORDER_TYPE type; + + // + // Order state ... + ENUM_ORDER_STATE state; + + // + // Type of execution by remainder ... + ENUM_ORDER_TYPE_FILLING filling; + + // + // Order lifetime ... + ENUM_ORDER_TYPE_TIME lifetime; + + // + // Order ticket ... + ulong ticket; + + // + // Magic Number ... + long magic; + + // + // Position id, that is placed on order, + // when it is executed. Each executed order invokes a + // deal, that opens new or changes existing + // position. Id of that position is placed on + // executed order in this moment. + long positionId; + + // + // Initial volume on order placement ... + double initialVolume; + + // + // Unfilled volume ... + double currentVolume; + + // + // Price, specified in the order ... + double openPrice; + + // + // Current price by order symbol ... + double currentPrice; + + // + // Price of placing Limit order when StopLimit order is triggered ... + double stopLimitPrice; + + // + // Take Profit level ... + double tp; + + // + // Stop Loss level ... + double sl; + + // + // Trading Symbol ... + string symbol; + + // + // Signal Provider ... + string provider; + + // + // Order Comment ... + string comment; + + // + ENUM_TIMEFRAMES period; + + // + // Constructor ... + XOrder() + { + Clean(); + } + + // + // Initializers ... + bool ByIndex( + int index // Fill By Index ... + ) + { + // + bool result = false; + + // + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + static COrderInfo mOrderInfo; + + // + result = mOrderInfo.SelectByIndex(index); + if (!result) + { + return result; + } + + // + // Reading Order Info ... + magic = mOrderInfo.Magic(); + sl = mOrderInfo.StopLoss(); + tp = mOrderInfo.TakeProfit(); + ticket = mOrderInfo.Ticket(); + openPrice = mOrderInfo.PriceOpen(); + positionId = mOrderInfo.PositionId(); + currentPrice = mOrderInfo.PriceCurrent(); + initialVolume = mOrderInfo.VolumeInitial(); + currentVolume = mOrderInfo.VolumeCurrent(); + stopLimitPrice = mOrderInfo.PriceStopLimit(); + + // + symbol = mOrderInfo.Symbol(); + comment = mOrderInfo.Comment(); + + // + state = mOrderInfo.State(); + type = mOrderInfo.OrderType(); + lifetime = mOrderInfo.TypeTime(); + filling = mOrderInfo.TypeFilling(); + + // + setupAt = mOrderInfo.TimeSetup(); + executedAt = mOrderInfo.TimeDone(); + expiredAt = mOrderInfo.TimeExpiration(); + + // + period = ExtractPeriod(comment); + provider = ExtractProvider(comment); + + // + result = IsValid(); + + // + return result; + } + + // + // Retrieve Specific History Order ... + bool HistoryByIndex( + int index // Fill By Index ... + ) + { + // + bool result = false; + + // + int ordersCount = HistoryOrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + static CHistoryOrderInfo mOrderInfo; + + // + result = mOrderInfo.SelectByIndex(index); + if (!result) + { + return result; + } + + // + // Reading Order Info ... + magic = mOrderInfo.Magic(); + sl = mOrderInfo.StopLoss(); + tp = mOrderInfo.TakeProfit(); + ticket = mOrderInfo.Ticket(); + openPrice = mOrderInfo.PriceOpen(); + positionId = mOrderInfo.PositionId(); + currentPrice = mOrderInfo.PriceCurrent(); + initialVolume = mOrderInfo.VolumeInitial(); + currentVolume = mOrderInfo.VolumeCurrent(); + stopLimitPrice = mOrderInfo.PriceStopLimit(); + + // + symbol = mOrderInfo.Symbol(); + comment = mOrderInfo.Comment(); + + // + state = mOrderInfo.State(); + type = mOrderInfo.OrderType(); + lifetime = mOrderInfo.TypeTime(); + filling = mOrderInfo.TypeFilling(); + + // + setupAt = mOrderInfo.TimeSetup(); + executedAt = mOrderInfo.TimeDone(); + expiredAt = mOrderInfo.TimeExpiration(); + + // + period = ExtractPeriod(comment); + provider = ExtractProvider(comment); + + // + result = IsValid(); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + tp = 0; + sl = 0; + magic = 0; + ticket = 0; + positionId = 0; + openPrice = 0; + currentPrice = 0; + initialVolume = 0; + currentVolume = 0; + stopLimitPrice = 0; + + // + setupAt = NULL; + expiredAt = NULL; + executedAt = NULL; + + // + symbol = NULL; + comment = NULL; + provider = NULL; + + // + type = NULL; + state = NULL; + period = NULL; + filling = NULL; + lifetime = NULL; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + NotEmpty(ticket) && + NotEmpty(positionId) + // + ; + + // + return result; + } + + // + // Calculate Age ... + int GetAge( + ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period + ) + { + return GetAge(this, mPeriod); + } + + // + // Check this instance is Same os Given instance or not ... + bool IsSameAs( + const XOrder &value // instance for Compare + ) + { + // + bool result = false; + + // + result = + // + type == value.type && + state == value.state && + magic == value.magic && + ticket == value.ticket && + symbol == value.symbol && + provider == value.provider && + positionId == value.positionId + // + ; + + // + return result; + } + + // + // Find index in a Collection ... + int FindIndex( + const XOrder &values[] // Collection to Find + ) + { + // + return FindIndex( + this, + values + // + ); + } + + // + // Check Items Passed Specific Filters or not ... + bool IsFiltersPassed( + string mSymbol = NULL, // Trading Symbol + string mProvider = NULL, // Signal Provider + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe + ENUM_ORDER_TYPE mType = NULL, // Long (Buy), Short (Sell) + ENUM_ORDER_STATE mState = NULL, // Order State + ulong mMagic = NULL, // Magic Number + bool mFilterByMagic = true // Get Only Self Open Positions + ) + { + // + bool result = false; + + // + result = + // + // Magic Filter ... + IsMagicFilterPassed( + mMagic, + mFilterByMagic, + this + // + ) + // + && + // + // Symbol Filter ... + IsSymbolFilterPassed( + mSymbol, + this + // + ) + // + && + // + // Provider Filter ... + IsProviderFilterPassed( + mProvider, + this + // + ) + // + && + // + // Period Filter ... + IsPeriodFilterPassed( + mPeriod, + this + // + ) + // + && + // + // Type Filter ... + IsTypeFilterPassed( + mType, + this + // + ) + // + && + // + // State Filter ... + IsStateFilterPassed( + mState, + this + // + ) + // + ; + + // + return result; + } +}; + +// +// Model a Deal ... +struct XDeal +{ + // + // the ID of the Expert Advisor, that executed the deal ... + ulong magic; + + // + // the ID of position, in which the deal was involved ... + ulong positionId; + + // + // Ticket ... + ulong ticket; + + // + // the name of the deal symbol ... + string symbol; + + // + // order by which the deal is executed ... + ulong order; + + // + // the time of deal execution ... + datetime time; + + // + // Deal price ... + double price; + + // + // the financial result of the deal (in deposit currency) ... + double profit; + + // + // the amount of swap when position is closed ... + double swap; + + // + // the amount of commission of the deal ... + double commission; + + // + // the volume of deal ... + double volume; + + // + // the deal comment ... + string comment; + + // + string provider; + + // + ENUM_TIMEFRAMES period; + + // + // the deal type ... + // ------------------------------------------------------------------ + // DEAL_TYPE_BUY => Buy ... + // DEAL_TYPE_SELL => Sell ... + // DEAL_TYPE_BUY_CANCELED => Canceled buy deal ... + // There can be a situation when a previously executed buy deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ... + // + // DEAL_TYPE_SELL_CANCELED => Canceled sell deal ... + // There can be a situation when a previously executed sell deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation + // + // DEAL_TYPE_BALANCE => Balance ... + // DEAL_TYPE_CREDIT => Credit ... + // DEAL_TYPE_CHARGE => Additional charge ... + // DEAL_TYPE_CORRECTION => Correction ... + // DEAL_TAX => Tax charges ... + // DEAL_TYPE_BONUS => Bonus ... + // DEAL_TYPE_INTEREST => Interest rate ... + // DEAL_DIVIDEND => Dividend operations... + // DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ... + // DEAL_TYPE_COMMISSION => Additional commission ... + // DEAL_TYPE_COMMISSION_DAILY => Daily commission ... + // DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ... + // DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ... + // DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission + ENUM_DEAL_TYPE type; + + // + // the deal direction ... + // ---------------------------------- + // DEAL_ENTRY_IN => Entry in ... + // DEAL_ENTRY_OUT => Entry out ... + // DEAL_ENTRY_INOUT => Reverse ... + // DEAL_ENTRY_OUT_BY => Close a position by an opposite one ... + ENUM_DEAL_ENTRY entry; + + // + // deal reson ... + // --------------------- + // DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ... + // DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ... + // DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ... + // DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ... + // DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ... + // DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ... + // DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ... + // DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ... + // DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ... + // DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ... + ENUM_DEAL_REASON reason; + + // + // Constructor ... + XDeal() + { + Clean(); + } + + // + // Initializers ... + bool ByIndex( + int index // Deal Index + ) + { + // + bool result = false; + + // + int dealsCount = HistoryDealsTotal(); + result = dealsCount > 0; + if (!result) + { + return result; + } + + // + static CDealInfo mDealInfo; + + // + result = mDealInfo.SelectByIndex(index); + if (!result) + { + // + return result; + } + + // + // Reading Order Info ... + swap = mDealInfo.Swap(); + magic = mDealInfo.Magic(); + order = mDealInfo.Order(); + ticket = mDealInfo.Ticket(); + time = mDealInfo.Time(); + price = mDealInfo.Price(); + symbol = mDealInfo.Symbol(); + profit = mDealInfo.Profit(); + volume = mDealInfo.Volume(); + comment = mDealInfo.Comment(); + positionId = mDealInfo.PositionId(); + entry = mDealInfo.Entry(); + commission = mDealInfo.Commission(); + type = mDealInfo.DealType(); + reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( + ticket, + DEAL_REASON); + + // + period = ExtractPeriod(comment); + provider = ExtractProvider(comment); + + // + result = IsValid(); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + magic = 0; + positionId = 0; + ticket = 0; + order = 0; + time = 0; + price = 0; + profit = 0; + swap = 0; + commission = 0; + volume = 0; + + // + symbol = NULL; + comment = NULL; + provider = NULL; + + // + type = NULL; + entry = NULL; + period = NULL; + reason = NULL; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + NotEmpty(ticket) && + NotEmpty(positionId) + // + ; + + // + return result; + } + + // + // Calculate Age ... + int GetAge( + ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period + ) + { + return GetAge(this, mPeriod); + } + + // + // Check this instance is Same os Given instance or not ... + bool IsSameAs( + const XDeal &value // instance for Compare + ) + { + // + bool result = false; + + // + result = + // + type == value.type && + magic == value.magic && + entry == value.entry && + reason == value.reason && + ticket == value.ticket && + volume == value.volume && + symbol == value.symbol && + provider == value.provider && + positionId == value.positionId + // + ; + + // + return result; + } + + // + // Find index in a Collection ... + int FindIndex( + const XDeal &values[] // Collection to Find + ) + { + // + return FindIndex( + this, + values + // + ); + } + + // + // Check Items Passed Specific Filters or not ... + bool IsFiltersPassed( + string mSymbol = NULL, // Trading Symbol + string mProvider = NULL, // Signal Provider + ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe + ENUM_DEAL_TYPE mType = NULL, // Deal Type + ENUM_DEAL_ENTRY mEntry = NULL, // Deal Entry + ENUM_DEAL_REASON mReason = NULL, // Deal Reason + ulong mMagic = NULL, // Magic Number + bool mFilterByMagic = true // Get Only Self Open Positions + ) + { + // + bool result = false; + + // + result = + // + // Magic Filter ... + IsMagicFilterPassed( + mMagic, + mFilterByMagic, + this + // + ) + // + && + // + // Symbol Filter ... + IsSymbolFilterPassed( + mSymbol, + this + // + ) + // + && + // + // Provider Filter ... + IsProviderFilterPassed( + mProvider, + this + // + ) + // + && + // + // Period Filter ... + IsPeriodFilterPassed( + mPeriod, + this + // + ) + // + && + // + // Type Filter ... + IsTypeFilterPassed( + mType, + this + // + ) + // + && + // + // Entry Filter ... + IsEntryFilterPassed( + mEntry, + this + // + ) + // + && + // + // Reason Filter ... + IsReasonFilterPassed( + mReason, + this + // + ) + // + ; + + // + return result; + } +}; + +// +// Model OnTrade Event Handler Result on XCTrade Class ... +struct XOnTradeHandlerState +{ + // + bool hasNewDeal; + int newDeals; + + // + bool hasNewOrder; + int newOrders; + + // + bool hasNewPosition; + int newPositions; + + // + bool hasNewHistoryOrder; + int newHistoryOrders; + + // + // Constructor ... + XOnTradeHandlerState() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + hasNewDeal = false; + hasNewOrder = false; + hasNewPosition = false; + hasNewHistoryOrder = false; + + // + newDeals = 0; + newOrders = 0; + newPositions = 0; + newHistoryOrders = 0; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + ( + // + hasNewDeal + ? newDeals > 0 + : true + // + ) + // + && + // + ( + // + hasNewOrder + ? newOrders > 0 + : true + // + ) + // + && + // + ( + // + hasNewPosition + ? newPositions > 0 + : true + // + ) + // + && + // + ( + // + hasNewHistoryOrder + ? newHistoryOrders > 0 + : true + // + ) + // + ; + + // + return result; + } +}; + +// +// Model Guard Info ... +struct XGuard +{ + // + string symbol; // Trading Symbol ... + string provider; // Signal Provider ... + ENUM_TIMEFRAMES period; // Trading Timeframe ... + ENUM_POSITION_TYPE type; // Position Type ... + ENUM_X_GUARD_ACTIONS action; // Which Action to Do ... + + // + double dblPayLoad; + string strPayload; + + // + // Constructor ... + XGuard() + { + Clean(); + } + + // + // Initialize ... + + // + // Global Initializer ... + bool Init( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Timeframe ... + ENUM_X_GUARD_ACTIONS mAction, // Which Action to Do ... + ENUM_POSITION_TYPE mType = NULL, // Position Type ... + string mProvider = NULL, // Signal Provider ... + double mDblPayLoad = NULL, + string mStrPayload = NULL // + ) + { + // + type = mType; + symbol = mSymbol; + period = mPeriod; + action = mAction; + provider = mProvider; + dblPayLoad = mDblPayLoad; + strPayload = mStrPayload; + + // + bool result = IsValid(); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + provider = NULL; + period = NULL; + action = X_GUARD_ACTION_NOTHING; + + // + strPayload = NULL; + dblPayLoad = EMPTY_VALUE; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + action != X_GUARD_ACTION_NOTHING + // + ; + + // + return result; + } +}; + +// +// Model a Position with all of it's Supports ... +struct XPositionPack +{ + // + ulong ticket; // Main Position's Ticket + + // + XPosition position; // Main Position (if Exists) + + // + int supportOrdersCount; // Supported Orders (Untriggered) + int supportPositionsCount; // Supported Positions + + // + XOrder supportOrders[]; // Supported Orders (Untriggered) + XPosition supportPositions[]; // Supported Positions + + // + // Constructor ... + XPositionPack() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + ticket = 0; + + // + position.Clean(); + + // + supportOrdersCount = 0; + supportPositionsCount = 0; + + // + Clean(supportOrders); + Clean(supportPositions); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + NotEmpty(ticket) && + ( + // + supportOrdersCount > 0 + ? ArraySize(supportOrders) == supportOrdersCount + : true + // + ) + // + && + // + ( + // + supportPositionsCount > 0 + ? ArraySize(supportPositions) == supportPositionsCount + : true + // + ) + // + ; + + // + return result; + } +}; + +// +// Check Position SL Trails Structure ... +struct XTrail +{ + // + ulong ticket; // Position Ticket ... + ENUM_POSITION_TYPE type; // Type ... + datetime time; // Trail Time ... + double before; // SL Value Before Trailing ... + double after; // SL Value After Trailing ... + int level; // Number of Trails SL ... + double profit; // Profit in SL Time ... + + // + // Constructor ... + XTrail() + { + Clean(); + } + + // + // Tools ... + + // + bool Init( + ulong mTicket, // Ticket + ENUM_POSITION_TYPE mType, // Type + double mProfit, // Profit + double mBefore, // Before + double mAfter // After + ) + { + // + Clean(); + + // + type = mType; + after = mAfter; + ticket = mTicket; + before = mBefore; + profit = mProfit; + + // + level++; + + // + time = TimeCurrent(); + + // + return IsValid(); + } + + // + bool Update( + double mSl, // new SL ... + double mProfit // Profit + ) + { + // + bool result = false; + + // + time = TimeCurrent(); + + // + double cAfter = after; + after = mSl; + before = cAfter; + profit = mProfit; + + // + level++; + + // + result = IsValid(); + + // + return result; + } + + // + string GenerateTag() + { + // + string result = NULL; + + // + string ticketLevelStr = ToString(ticket) + "," + ToString(level); + + // + result = Surround( + XSLTrailToken, + ticketLevelStr // + ); + + // + return result; + } + + // + // Cleanup ... + void Clean() + { + // + ticket = 0; + time = 0; + before = 0; + after = 0; + level = 0; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + ticket > 0 && + time > 0 && + level > 0 + // + ; + + // + return result; + } +}; + +// +// TypeDefs ... + +// +typedef void (*TOnDealsChanged)(int count); + +// +typedef void (*TOnOrdersChanged)(int count); + +// +typedef void (*TOnPositionsChanged)(int count); + +// +typedef void (*TOnStopLoss)(const XDeal &deal); +typedef void (*TOnTakeProfit)(const XDeal &deal); + +// +typedef void (*TOnTradeStateChanged)(const XOnTradeHandlerState &state); + +// +// Classes ... + +// +// Create a Signal Specfic Data Collector ... +class XSCSignalCollector +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + void XSCSignalCollector() + { + // + XSCDataCollector mBase; + mBase.Clear(); + } + + // + // Deconstructor ... + + // + // Tools ... + + // + // Inheritanced Functions ... + + // + // Cleaning Store ... + void Clear() + { + // + XSCDataCollector mBase; + + // + mBase.Clear(); + } + + // + // Collect All Store ... + int Collect(XSignal &result[]) + { + // + int mResult = 0; + + // + XSCDataCollector mBase; + + // + mResult = mBase.Collect(result); + + // + return mResult; + } + + // + // Add Item To Store ... + bool Add(XSignal &item) + { + // + bool result = false; + + // + XSCDataCollector mBase; + + // + result = mBase.Add(item); + + // + return result; + } + + // + // Add Item(s) To Store ... + int Add(XSignal &items[]) + { + // + int result = 0; + + // + XSCDataCollector mBase; + + // + result = mBase.Add(items); + + // + return result; + } + + // + // Remove an Item from Store ... + bool Remove(XSignal &item) + { + // + bool result = false; + + // + XSCDataCollector mBase; + + // + result = mBase.Remove(item); + + // + return result; + } + + // + // Custom Functions ... + + // + int CollectSignals( + XSignal &result[], // Hold Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Timeframe + ENUM_POSITION_TYPE type = NULL, // Long (Buy), Short (Sell) + ENUM_X_ORDER_MODES mode = NULL // Execution Mode + ) + { + // + int mResult = 0; + + // + XSignal signals[]; + int signalsCount = Collect(signals); + if (signalsCount <= 0) + { + return mResult; + } + + // + mResult = ArraySize(result); + + // + // Now we Have to Apply Filters ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isFiltersPassed = + iSignal.IsFiltersPassed( + symbol, + provider, + period, + type, + mode + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + AddRef( + iSignal, + result + // + ); + } + + // + return mResult; + } + + // + // Protected ... +protected: + // + // Tools ... + + // + // Private ... +private: + // + // Props ... + + // + // Tools ... +}; + +// +// Tools ... + +// +bool IsValid(ENUM_X_ORDER_MODES value) +{ + return value != X_ORDER_MODE_NOTHING; +} + +// +// Ages ... + +// +// Retrieve a Position Age ... +int GetAge( + XPosition &position, // Selected Position ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + position.symbol, + period, + position.openAt); + + // + return result; +} + +// +// Retrieve an Order Age ... +int GetAge( + XOrder &order, // Selected Order ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + order.symbol, + period, + order.setupAt); + + // + return result; +} + +// +// Retrieve a Deal Age ... +int GetAge( + XDeal &deal, // Selected Deal ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + deal.symbol, + period, + deal.time); + + // + return result; +} + +// +// Get Oldest Deal ... +int GetOldest( + XDeal &item, // Hold Result ... + XDeal &items[] // Source Array ... +) +{ + // + int result = -1; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XDeal tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XDeal iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Youngest Deal ... +int GetYoungest( + XDeal &item, // Hold Result ... + XDeal &items[] // Source Array ... +) +{ + // + int result = -1; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XDeal tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XDeal iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge > iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Oldest Order ... +int GetOldest( + XOrder &item, // Hold Result ... + XOrder &items[] // Source Array ... +) +{ + // + int result = -1; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XOrder tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XOrder iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Youngest Order ... +int GetYoungest( + XOrder &item, // Hold Result ... + XOrder &items[] // Source Array ... +) +{ + // + int result = -1; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XOrder tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XOrder iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge > iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Oldes Position ... +int GetOldest( + XPosition &item, // Hold Result ... + XPosition &items[] // Source Array ... +) +{ + // + int result = -1; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XPosition tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Youngest Position ... +int GetYoungest( + XPosition &item, // Hold Result ... + XPosition &items[] // Source Array ... +) +{ + // + int result = -1; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XPosition tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge > iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Check Filters ... + +// +// Magic Filter ... +template +bool IsMagicFilterPassed( + ulong magic, + bool filterByMagic, + T &item + // +) +{ + // + return !filterByMagic + ? true + : !NotEmpty(magic) + ? false + : magic == item.magic; +} + +// +// Symbol Filter ... +template +bool IsSymbolFilterPassed( + string symbol, + T &item + // +) +{ + // + return !IsValid(symbol) + ? true + : symbol == item.symbol; +} + +// +// Provider Filter ... +template +bool IsProviderFilterPassed( + string provider, + T &item + // +) +{ + // + return !IsValid(provider) + ? true + : provider == item.provider; +} + +// +// Period Filter ... +template +bool IsPeriodFilterPassed( + ENUM_TIMEFRAMES period, + T &item + // +) +{ + // + return !IsValid(period) + ? true + : period == item.period; +} + +// +// Type Filter ... +template +bool IsTypeFilterPassed( + ENUM_POSITION_TYPE type, + T &item + // +) +{ + // + return type == NULL + ? true + : type == item.type; +} +template +bool IsTypeFilterPassed( + ENUM_ORDER_TYPE type, + T &item + // +) +{ + // + return type == NULL + ? true + : type == item.type; +} +template +bool IsTypeFilterPassed( + ENUM_DEAL_TYPE type, + T &item + // +) +{ + // + return type == NULL + ? true + : type == item.type; +} + +// +// Mode Filter ... +template +bool IsModeFilterPassed( + ENUM_X_ORDER_MODES mode, + T &item + // +) +{ + // + return mode == NULL + ? true + : mode == item.mode; +} + +// +// Entry Filter ... +template +bool IsEntryFilterPassed( + ENUM_DEAL_ENTRY entry, + T &item + // +) +{ + // + return entry == NULL + ? true + : entry == item.entry; +} + +// +// Reason Filter ... +template +bool IsReasonFilterPassed( + ENUM_DEAL_REASON reason, + T &item + // +) +{ + // + return reason == NULL + ? true + : reason == item.reason; +} + +// +// State Filter ... +template +bool IsStateFilterPassed( + ENUM_ORDER_STATE state, + T &item + // +) +{ + // + return state == NULL + ? true + : state == item.state; +} + +// + +// +// Find Specific Item Index inside a Collection ... +template +int FindIndex( + T &item, // Item to Find + const T &items[] // Items for Search +) +{ + // + int result = -1; + + // + // Check Item Validation ... + if (!item.IsValid()) + { + return result; + } + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + T iItem = items[i]; + + // + // Validate Item ... + if (!iItem.IsValid()) + { + continue; + } + + // + bool isSame = item.IsSameAs(iItem); + if (isSame && result <= -1) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// +// Calculate Positions Profit Summary ... +double SpecifiedCalculatePositionsProfit( + XPosition &positions[] // Source +) +{ + // + double result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + result += iPosition.profit; + } + + // + return result; +} + +// +// Calculate Required Profit for Hedging ... +double SpecifiedCalculateRequiredProfitForHedge( + XPosition &positions[], // Source + double mMinProfitPerTrade, + double mMinProfitPerVolumeFactor // +) +{ + // + double result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + bool isHedgingEnable = mMinProfitPerTrade > 0 && mMinProfitPerVolumeFactor > 0; + if (!isHedgingEnable) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + if (mMinProfitPerTrade > 0 && mMinProfitPerVolumeFactor > 0) + { + // + result += + ((iPosition.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * iPosition.swap); + } + } + + // + return result; +} + +// +bool SpecifiedIsPositionsReadyForHedge( + XPosition &positions[], // Source + double mMinProfitPerTrade, + double mMinProfitPerVolumeFactor // +) +{ + // + double profit = SpecifiedCalculatePositionsProfit(positions); + double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( + positions, + mMinProfitPerTrade, + mMinProfitPerVolumeFactor // + ); + + // + bool result = requiredProfit > 0 + ? profit >= requiredProfit + : profit > requiredProfit; + + // + return result; +} + +// +// Retrieve String Representation ... +string ToString(ENUM_X_SIGNAL_EXECUTION_RESULT value) +{ + // + string result = NULL; + + // + switch (value) + { + // + case X_SIGNAL_EXECUTION_UNKNOWN: + result = "Unknown"; + break; + + // + case X_SIGNAL_EXECUTION_SUCCEED: + result = "Succed"; + break; + + // + case X_SIGNAL_EXECUTION_FAILED_SPREAD: + result = "Spread more than Max Allowed"; + break; + + // + case X_SIGNAL_EXECUTION_FAILED_NO_EQUITY: + result = "No Equity for Trade"; + break; + + // + case X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR: + result = "Price Error"; + break; + + // + case X_SIGNAL_EXECUTION_FAILED_MAX_REACHED: + result = "Max Allowed Positions Reached"; + break; + + // + case X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS: + result = "Invalid Params"; + break; + } + + // + return result; +} + +// +// Converts Position Type to Order Type ... +ENUM_ORDER_TYPE ToOrderType(ENUM_POSITION_TYPE value) +{ + // + bool isLong = IsLong(value); + + // + ENUM_ORDER_TYPE result = + isLong + ? ORDER_TYPE_BUY + : ORDER_TYPE_SELL; + + // + return result; +} + +// +// Tagging ... + +// +// Generate Specified Tag for Using in Comments ... +string GeneratePeriodTag(ENUM_TIMEFRAMES period) +{ + // + string strPeriod = ToString(period); + return Surround( + XPeriodToken, + strPeriod + // + ); +} + +// +// Extract Period from a Tagged string ... +ENUM_TIMEFRAMES ExtractPeriod(string value) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + string pStr = ParseStringSurrounded( + value, + XPeriodToken + // + ); + if (!IsValid(pStr)) + { + return result; + } + + // + result = ToPeriod(pStr); + + // + return result; +} + +// Generate Specified Tag for Using in Comments ... +string GenerateProviderTag(string provider) +{ + // + return Surround( + XProviderToken, + provider + // + ); +} + +// +// Extract Provider from a Tagged string ... +string ExtractProvider(string value) +{ + // + return ParseStringSurrounded( + value, + XProviderToken + // + ); +} + +// +// Generate Support Comment Tag ... +string GenerateSupportTag(ulong ticket) +{ + // + return Surround( + XSupportToken, + ticket + // + ); +} + +// +// Extract Support Positions from a Tagged string ... +ulong ExtractSupportedTicket(string value) +{ + // + return ParseLongSurrounded( + value, + XSupportToken + // + ); +} + +// +// Generate EQM Support Comment Tag ... +string GenerateEQMSupportTag(ulong ticket) +{ + // + return Surround( + XEQMSupportToken, + ticket + // + ); +} + +// +// Extract EQM Support Positions from a Tagged string ... +ulong ExtractEQMSupportedTicket(string value) +{ + // + return ParseLongSurrounded( + value, + XEQMSupportToken + // + ); +} + +// +// SL Trails ... + +// +// Extract SL Trail Level ... +int ExtractSLTrailLevel(string comment) +{ + // + int result = 0; + + // + if (!IsValid(comment)) + { + return result; + } + + // + result = ParseIntSurrounded( + comment, + XSLTrailToken + // + ); + + // + return result; +} + +// +// Generate SL Trail Comment Tag ... +string GenerateSLTrailTag(int level) +{ + // + string result = NULL; + + // + if (level <= 0) + { + return result; + } + + // + result = Surround( + XSLTrailToken, + level + // + ); + + // + return result; +} + +// +// Prepare SL Trail Comment ... +string PrepareSLTrailTag( + const string comment // Original Position Comment ... +) +{ + // + string result = NULL; + + // + int level = 0; + result = comment; + + // + // Check Comment Contains SL Trailing or not ... + int lastTrailLevel = ExtractSLTrailLevel(comment); + if (lastTrailLevel <= 0) + { + level++; + } + else + { + // + level = lastTrailLevel + 1; + string lastLevelStr = GenerateSLTrailTag(lastTrailLevel); + StringReplace( + result, + lastLevelStr, + "" + // + ); + } + + // + // Generate level Comment ... + string levelStr = GenerateSLTrailTag(level); + result += levelStr; + + // + return result; +} + +// +// EQM Support Orders ... + +// +int GenerateEQMOrders( + XSignal &orders[], // Result + XPosition &position, // Supported Position + XOHCLSupRes &supRes, // Data Source + bool longs = true, + bool shorts = true // +) +{ + // + int result = 0; + + // + Clean(orders); + + // + if (!supRes.IsValid() || + !position.IsValid()) + { + return result; + } + + // + if (longs) + { + // + double longLevels[]; + + // + Copy( + supRes.res, + longLevels // + ); + + // + double minSup = GetMin( + supRes.sup // + ); + if (minSup > 0) + { + // + Add( + minSup, + longLevels // + ); + } + + // + ArraySort(longLevels); + + // + if (ArraySize(longLevels) > 2) + { + // + for (int i = 0; i < ArraySize(longLevels) - 2; i++) + { + // + double iSL = longLevels[i]; + double iEntry = longLevels[i + 1]; + double iTP = longLevels[i + 2]; + + // + XSignal iSignal; + bool isPrepared = iSignal.PrepareStopLong( + position.symbol, + XEQMSupportToken, + position.period, + iEntry, + position.volume, + X_SIGNAL_USE_NOTHING, + iSL, + iTP // + ); + if (isPrepared) + { + // + string comment = GenerateSupportTag(position.ticket); + iSignal.comment = comment; + + // + AddRef( + iSignal, + orders // + ); + } + } + } + } + + // + if (shorts) + { + // + double shortLevels[]; + + // + Copy( + supRes.sup, + shortLevels // + ); + + // + double maxRes = GetMax( + supRes.res // + ); + if (maxRes > 0) + { + // + Add( + maxRes, + shortLevels // + ); + } + + // + ArraySort(shortLevels); + ArrayReverse(shortLevels); + + // + if (ArraySize(shortLevels) > 2) + { + // + for (int i = 0; i < ArraySize(shortLevels) - 2; i++) + { + // + double iSL = shortLevels[i]; + double iEntry = shortLevels[i + 1]; + double iTP = shortLevels[i + 2]; + + // + XSignal iSignal; + bool isPrepared = iSignal.PrepareStopShort( + position.symbol, + XEQMSupportToken, + position.period, + iEntry, + position.volume, + X_SIGNAL_USE_NOTHING, + iSL, + iTP // + ); + if (isPrepared) + { + // + string comment = GenerateSupportTag(position.ticket); + iSignal.comment = comment; + + // + AddRef( + iSignal, + orders // + ); + } + } + } + } + + // + result = ArraySize(orders); + + // + return result; +} + +// +// Count Positions from a Collection ... +void CountPositions( + const XPosition &positions[], + int &longs, + double &longProfits, + double &longVolumes, // + // + int &shorts, + double &shortProfits, + double &shortVolumes // +) +{ + // + longs = 0; + longProfits = 0; + longVolumes = 0; + + // + shorts = 0; + shortProfits = 0; + shortVolumes = 0; + + // + int positionsCount = ArraySize(positions); + if (!IsValidSize(positionsCount)) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isLong = IsLong(iPosition.type); + if (isLong) + { + // + longs++; + longProfits += iPosition.profit; + longVolumes = iPosition.volume; + } + else + { + // + shorts++; + shortProfits += iPosition.profit; + shortVolumes = iPosition.volume; + } + } +} \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/compile.js b/MQLTestWorkspace/BKPS/14030309/compile.js new file mode 100644 index 0000000..6db4a8a --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/compile.js @@ -0,0 +1,427 @@ +// +// Import Requirements ... +const execSync = require("child_process").execSync; +const XFileTools = require("./Documents/JsModules/x-file.tools"); +const XShellTools = require("./Documents/JsModules/x-shell.tools"); +const XColorTools = require("./Documents/JsModules/x-color.tools"); + +// +// define constants ... +const projectsPath = XFileTools.joinPath(".", "Projects"); +const packsPath = XFileTools.joinPath(".", "Packs"); +const excludeWorkspaceFolders = [ + "BKP", + "Documents", + "Images", + "Includes", + "Logs", + "Packs", + "Profiles", + "Projects", + "Scripts", + "Services", + "Shared Projects", + // + // Exclude Defaults ... + "Examples", + "Free Indicators", + "Advisors", + "Free Robots" +]; + +// +// Read Command Arguments ... +let projectName = process.argv[2]; +let doPackProject = process.argv[3] || false; + +// +// Make Decission to what to Do based on given args ... +if (!projectName || + projectName == "" || + projectName.length == 0) { + // + // Compile Whole MQL Workspace ... + doPackProject = false; + const workSpacePath = XFileTools.joinPath(".", __dirname); + + // + doWorkspaceCompile(workSpacePath); +} else if (projectName == "--experts" || projectName == "**experts") { + // + // Compile Experts on Workspace ... + doPackProject = false; + const workSpacePath = XFileTools.joinPath(".", __dirname, "Experts"); + + // + doWorkspaceCompile(workSpacePath); +} else if (projectName == "--helpers" || projectName == "**helpers") { + // + // Compile Helpers on Workspace ... + doPackProject = false; + const workSpacePath = XFileTools.joinPath(".", __dirname, "Helpers"); + + // + doWorkspaceCompile(workSpacePath); +} else if (projectName == "--classes" || projectName == "**classes") { + // + // Compile Classes on Workspace ... + doPackProject = false; + const workSpacePath = XFileTools.joinPath(".", __dirname, "Classes"); + + // + doWorkspaceCompile(workSpacePath); +} else if (projectName == "--indicators" || projectName == "**indicators") { + // + // Compile Indicators on Workspace ... + doPackProject = false; + const workSpacePath = XFileTools.joinPath(".", __dirname, "Indicators"); + + // + doWorkspaceCompile(workSpacePath); +} else if (projectName == "--libraries" || projectName == "**libraries") { + // + // Compile Libraries on Workspace ... + doPackProject = false; + const workSpacePath = XFileTools.joinPath(".", __dirname, "Libraries"); + + // + doWorkspaceCompile(workSpacePath); +} else { + // + // Compile Specific Projects ... + // + // Prepare Project Folder Path ... + const prjPath = XFileTools.joinPath(projectsPath, projectName); + + // + // Check Project Folder Exists ... + const isProjectFolderExists = XFileTools.isDirectoryExists(prjPath); + if (!isProjectFolderExists) { + // + const msg = "Project doesn't Exists ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + + // + // Call Handler Function ... + doProjectCompile(prjPath); +} + +// +async function doProjectCompile(path = "") { + // + let result = await handleProjectCompile(path); + if (result && doPackProject) { + result = await handleProjectPack(path); + } +} + +// +async function doWorkspaceCompile(path = "") { + // + let mustCompileFiles = await readMQLFiles(path); + + // + if (mustCompileFiles && mustCompileFiles.length > 0) { + // + // Loop through items ... + for (const f of mustCompileFiles) { + // + // Check Exclude ... + const fBaseName = XFileTools.basename(f); + let fPath = f.replace(fBaseName, ""); + let isExclude = false; + for (const e of excludeWorkspaceFolders) { + // + isExclude = fPath.includes(e); + if (isExclude) { + break; + } + } + + // + if (isExclude) { + continue; + } + + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to compile: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + const result = await compileMQLFile(f); + + // + if (result.includes("0 errors")) { + // + const msg = "compiled successfully ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)); + } else { + // + const msg = "failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + + // + return true; + } + + // + return false; +} + +/** + * read all content in project path and compile it one by one ... + * + * @param {string} path Project Path ... + */ +async function handleProjectCompile(path = "") { + // + let mustCompileFiles = await readMQLFiles(path); + + // + if (mustCompileFiles && mustCompileFiles.length > 0) { + // + // Loop through items ... + for (const f of mustCompileFiles) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to compile: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + const result = await compileMQLFile(f); + + // + if (result.includes("0 errors")) { + // + const msg = "compiled successfully ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)); + } else { + // + const msg = "failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + + // + return true; + } + + // + return false; +} + +/** + * Pack Compiled Project ... + * + * @param {string} path Project Path ... + */ +async function handleProjectPack(path = "") { + // + const projectName = XFileTools.basename(path); + + // + // check packs exists or not ... + const isPacksExists = XFileTools.isDirectoryExists(packsPath); + if (!isPacksExists) { + XFileTools.createDirectory(packsPath); + } + + // + // Reading Compiled Files ... + const mustCopyFiles = await readEXTFiles(path); + if (!mustCopyFiles || mustCopyFiles.length == 0) { + return false; + } + + // + const prjPackPath = XFileTools.joinPath(packsPath, projectName); + + // + // Check Project Packs Folder ... + const isProjectPackExists = XFileTools.isDirectoryExists(prjPackPath); + if (isProjectPackExists) { + await XFileTools.removeDirectory(prjPackPath, true); + } + + // + // Create Empty Project Folder on Pack ... + XFileTools.createDirectory(prjPackPath); + + // + // Loop through Files ... + for (const f of mustCopyFiles) { + // + // Prepare Destination Path ... + const fBasePath = XFileTools.basename(f); + let fDestPath = f.replace(fBasePath, "") + .replace(projectsPath, packsPath); + fDestPath = fDestPath.substring(0, fDestPath.length - 1); + + // + const isFDestPathExists = XFileTools.isDirectoryExists(fDestPath); + if (!isFDestPathExists) { + XFileTools.createDirectory(fDestPath); + } + + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue), + XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(fDestPath, XColorTools.COLOR_NAMES.Magenta) + ); + + // + let result = await XFileTools.copyFile(f, fDestPath); + if (result) { + // + const msg = "copy successfully ..."; + console.log( + XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) + ); + } else { + // + const msg = "copy failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + + // + return true; +} + +/** + * Extract Project MQL files ... + * + * @param {string} path Folder Path ... + * @returns + */ +async function readMQLFiles(path = "") { + // + const result = await extractFiles(path, [".mq5", ".mq4"]); + + // + return result; +} + +/** + * Extract Project Compiled files ... + * + * @param {string} path Folder Path ... + * @returns + */ +async function readEXTFiles(path = "") { + // + const result = await extractFiles(path, [".ex5", ".ex4"]); + + // + return result; +} + +/** + * Compile Specific MQL File ... + * + * @param {string} path MQL file path ... + * @returns + */ +async function compileMQLFile(path = "") { + // + // Check File Exists ... + const isExists = XFileTools.isFileExists(path); + if (!isExists) { + // + const msg = "file not found ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + + // + const ext = XFileTools.getFileExtension(path); + if (ext !== ".mq5" && ext !== "mq4") { + // + const msg = "invalid file extension ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + + // + const cwd = __dirname; + const cmd = "compile.cmd " + path; + + // + const result = await XShellTools.execute(cmd, cwd); + return result; +} + + +/** + * Extract Specific files from a folder and it's content ... + * + * @param {string} path Folder Path ... + * @returns + */ +async function extractFiles(path = "", ext = []) { + // + const result = []; + + // + if (!ext || ext.length == 0) { + return result; + } + + // + const pathContent = await XFileTools.getDirectoryContents(path); + if (!pathContent || pathContent.length == 0) { + return result; + } + + // + // Loop through Content ... + for (const c of pathContent) { + // + // Prepare full path ... + const cPath = XFileTools.joinPath(path, c); + + // + // check content path is file or not ... + const isCFile = XFileTools.isFileExists(cPath); + const isCDirectory = XFileTools.isDirectoryExists(cPath); + if (isCFile) { + // + // Check it is MQL file or not ... + const cExt = XFileTools.getFileExtension(cPath); + if (ext.includes(cExt)) { + result.push(cPath); + } + } else if (isCDirectory) { + // + const destFolderName = XFileTools.basename(cPath); + const isExcluded = excludeWorkspaceFolders.includes(destFolderName); + if (isExcluded) { + continue; + } + + // + const cFiles = await extractFiles(cPath, ext); + if (cFiles && cFiles.length > 0) { + result.push(...cFiles); + } + } + } + + // + return result; +} diff --git a/MQLTestWorkspace/BKPS/14030309/pack.js b/MQLTestWorkspace/BKPS/14030309/pack.js new file mode 100644 index 0000000..05f952b --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/pack.js @@ -0,0 +1,86 @@ +// +// Import Requirements ... +const execSync = require("child_process").execSync; +const XFileTools = require("./Documents/JsModules/x-file.tools"); +const XShellTools = require("./Documents/JsModules/x-shell.tools"); +const XColorTools = require("./Documents/JsModules/x-color.tools"); + +// +const packsPath = XFileTools.joinPath(".", "Packs"); + +handlePack(); +async function handlePack() { + // + var date = new Date(); + var folderName = date.toDateString() + .replace(" ", ""); + + // + const isPacksExists = XFileTools.isDirectoryExists(packsPath); + if (!isPacksExists) { + XFileTools.createDirectory(packsPath); + } + + // + const isProjectExists = XFileTools.isDirectoryExists(folderName); + if (!isProjectExists) { + XFileTools.createDirectory(folderName); + } + + // + const prjBasePath = XFileTools.joinPath(packsPath, folderName); + + // + var foldersPath = [ + "Classes", + "Experts", + "Helpers", + "Indicators", + "Libraries" + ]; + + // + for (const path of foldersPath) { + // + const fSourcePath = XFileTools.joinPath(".", path); + const fDestPath = XFileTools.joinPath(prjBasePath, path); + XFileTools.createDirectory(fDestPath); + + // + const filesToCopy = await XFileTools.extractFiles(fSourcePath, [".ex5", ".ex4"]); + if (!filesToCopy || filesToCopy.length == 0) { + return false; + } + + // + // Loop through Files ... + for (const f of filesToCopy) { + // + // Prepare Destination Path ... + + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue), + XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(fDestPath, XColorTools.COLOR_NAMES.Magenta) + ); + + // + let result = await XFileTools.copyFile(f, fDestPath); + if (result) { + // + const msg = "copy successfully ..."; + console.log( + XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) + ); + } else { + // + const msg = "copy failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + } +} \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/14030309/package.json b/MQLTestWorkspace/BKPS/14030309/package.json new file mode 100644 index 0000000..3671e81 --- /dev/null +++ b/MQLTestWorkspace/BKPS/14030309/package.json @@ -0,0 +1,43 @@ +{ + "name": "mql5", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "true": "", + "aaa": "|----------|", + "aab": "| Commons |", + "aac": "|----------|", + "compile": "node compile.js", + "pack": "node pack.js", + "compileWorkspace": "npm run compile", + "compileExperts": "npm run compile **experts", + "compileLibraries": "npm run compile **libraries", + "compileHelpers": "npm run compile **helpers", + "compileClasses": "npm run compile **classes", + "compileIndicators": "npm run compile **indicators", + "compileProject": "npm run compileExperts && npm run compileLibraries && npm run compileHelpers && npm run compileClasses && npm run compileIndicators", + "rmExperts": "shx --silent rm ./Experts/* || npm run true", + "rmHelpers": "shx --silent rm ./Helpers/* || npm run true", + "rmClasses": "shx --silent rm ./Classes/* || npm run true", + "rmLibraries": "shx --silent rm ./Libraries/* || npm run true", + "rmIndicators": "shx --silent rm ./Indicators/* || npm run true", + "rmExpertsEx": "shx --silent rm -r ./Experts/*.ex5 || npm run true", + "rmLibrariesEx": "shx --silent rm -r ./Libraries/*.ex5 || npm run true", + "rmHelpersEx": "shx --silent rm -r ./Helpers/*.ex5 || npm run true", + "rmClassesEx": "shx --silent rm -r ./Classes/*.ex5 || npm run true", + "rmIndicatorsEx": "shx --silent rm -r ./Indicators/*.ex5 || npm run true", + "cleanupEx": "npm run rmExpertsEx && npm run rmLibrariesEx && npm run rmHelpersEx && npm run rmClassesEx && npm run rmIndicatorsEx", + "prepareWorkspace": "npm run cleanupEx && npm run compileProject", + "generatePack": "npm run prepareWorkspace && npm run pack" + }, + "repository": { + "type": "git", + "url": "https://git.saherelmhub.ir/saherelm/MQL5TestWorkspace.git" + }, + "author": "Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)", + "license": "ISC", + "devDependencies": { + "shx": "^0.3.4" + } +} diff --git a/MQLTestWorkspace/BKPS/SingallingXTDNew.mq5 b/MQLTestWorkspace/BKPS/SingallingXTDNew.mq5 new file mode 100644 index 0000000..008cda6 --- /dev/null +++ b/MQLTestWorkspace/BKPS/SingallingXTDNew.mq5 @@ -0,0 +1,415 @@ + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + // XSTR ... + ENUM_XSTR_TREND_STATES cStrState = cMarket + .str + .GetState(cIndex); + double cStrTrend = cMarket.str.GetTrend(cIndex); + bool isCStrBullish = cStrState == X_STR_BULLISH; + bool isCStrBearish = cStrState == X_STR_BEARISH; + + // + ENUM_XSTR_TREND_STATES pStrState = cMarket + .str + .GetState(pIndex); + double pStrTrend = cMarket.str.GetTrend(pIndex); + bool isPStrBullish = pStrState == X_STR_BULLISH; + bool isPStrBearish = pStrState == X_STR_BEARISH; + + // + bool isTrendBullish = isCStrBullish; + bool isTrendBearish = isCStrBearish; + + // + bool isTrendSwitchedToBullish = + // + isCStrBullish && + !isPStrBullish + // + ; + + // + bool isTrendSwitchedToBearish = + // + isCStrBearish && + !isPStrBearish + // + ; + + // + // XCHE ... + + // + double cCHELongExit1 = cMarket.che.GetLongExit1(cIndex); + double cCHELongExit2 = cMarket.che.GetLongExit2(cIndex); + + // + double pCHELongExit1 = cMarket.che.GetLongExit1(pIndex); + double pCHELongExit2 = cMarket.che.GetLongExit2(pIndex); + + // + double cCHEShortExit1 = cMarket.che.GetShortExit1(cIndex); + double cCHEShortExit2 = cMarket.che.GetShortExit2(cIndex); + + // + double pCHEShortExit1 = cMarket.che.GetShortExit1(pIndex); + double pCHEShortExit2 = cMarket.che.GetShortExit2(pIndex); + + // + bool CCHEHasLongExit1 = NotEmpty(cCHELongExit1); + bool CCHEHasLongExit2 = NotEmpty(cCHELongExit2); + + // + bool CCHEHasShortExit1 = NotEmpty(cCHEShortExit1); + bool CCHEHasShortExit2 = NotEmpty(cCHEShortExit2); + + // + bool PCHEHasLongExit1 = NotEmpty(pCHELongExit1); + bool PCHEHasLongExit2 = NotEmpty(pCHELongExit2); + + // + bool PCHEHasShortExit1 = NotEmpty(pCHEShortExit1); + bool PCHEHasShortExit2 = NotEmpty(pCHEShortExit2); + + // + bool isCCHEBullish = + // + CCHEHasLongExit1 && + CCHEHasLongExit2 + // + ; + + // + bool isCCHEBearish = + // + CCHEHasShortExit1 && + CCHEHasShortExit2 + // + ; + + // + bool isPCHEBullish = + // + PCHEHasLongExit1 && + PCHEHasLongExit2 + // + ; + + // + bool isPCHEBearish = + // + PCHEHasShortExit1 && + PCHEHasShortExit2 + // + ; + + // + bool isCHEBullish = isCCHEBullish; + bool isCHEBearish = isCCHEBearish; + bool isCHESwitchedToBullish = + // + isCCHEBullish && + !isPCHEBullish + // + ; + bool isCHESwitchedToBearish = + // + isCCHEBearish && + !isPCHEBearish + // + ; + + // + // XPV ... + + double cPVPeak = cMarket.pv.GetPeak(cIndex); + double cPVVale = cMarket.pv.GetVale(cIndex); + + // + double pPVPeak = cMarket.pv.GetPeak(pIndex); + double pPVVale = cMarket.pv.GetVale(pIndex); + + // + double cPVSup = cMarket.pv.GetSupport(cIndex); + double pPVSup = cMarket.pv.GetSupport(pIndex); + + // + double cPVRes = cMarket.pv.GetResistance(cIndex); + double pPVRes = cMarket.pv.GetResistance(pIndex); + + // + double cPVFib1 = cMarket.pv.GetFib1(cIndex); + double cPVFib2 = cMarket.pv.GetFib2(cIndex); + double cPVFib3 = cMarket.pv.GetFib3(cIndex); + double cPVFib4 = cMarket.pv.GetFib4(cIndex); + double cPVFib5 = cMarket.pv.GetFib5(cIndex); + + // + double pPVFib1 = cMarket.pv.GetFib1(pIndex); + double pPVFib2 = cMarket.pv.GetFib2(pIndex); + double pPVFib3 = cMarket.pv.GetFib3(pIndex); + double pPVFib4 = cMarket.pv.GetFib4(pIndex); + double pPVFib5 = cMarket.pv.GetFib5(pIndex); + + // + bool isNewPeak = cPVPeak != pPVPeak; + bool isNewPeakUnderLast = + // + isNewPeak && + cPVPeak < pPVPeak + // + ; + bool isNewPeakOverLast = + // + isNewPeak && + cPVPeak > pPVPeak + // + ; + + // + bool isNewVale = cPVVale != pPVVale; + bool isNewValeUnderLast = + // + isNewVale && + cPVVale < pPVVale + // + ; + bool isNewValeOverLast = + // + isNewVale && + cPVVale > pPVVale + // + ; + + // + bool isFiboIncreased = + // + cPVFib1 > pPVFib1 && + cPVFib2 > pPVFib2 && + cPVFib3 > pPVFib3 && + cPVFib4 > pPVFib4 && + cPVFib5 > pPVFib5 + // + ; + + // + bool isFiboDecreased = + // + cPVFib1 < pPVFib1 && + cPVFib2 < pPVFib2 && + cPVFib3 < pPVFib3 && + cPVFib4 < pPVFib4 && + cPVFib5 < pPVFib5 + // + ; + + // + bool isFiboSectionChanged = + // + (isFiboDecreased && + isNewPeakUnderLast) + // + || + // + (isFiboIncreased && + isNewValeOverLast) + // + ; + + // + // XFI ... + + // + double cFI = fiHelper.GetMain(cIndex); + double pFI = fiHelper.GetMain(pIndex); + + // + bool isCFIOverZero = cFI > 0; + bool isCFIUnderZero = cFI > 0; + + // + bool isPFIOverZero = pFI > 0; + bool isPFIUnderZero = pFI > 0; + + // + bool isFICrossedOverZero = + // + isCFIOverZero && + !isPFIOverZero + // + ; + + // + bool isFICrossedUnderZero = + // + isCFIUnderZero && + !isPFIUnderZero + // + ; + + // + // XHK ... + + // + XOHCL cSMHKBar; + cMarket.hk.SMAsOHCL( + cSMHKBar, + cIndex // + ); + + // + XOHCL pSMHKBar; + cMarket.hk.SMAsOHCL( + pSMHKBar, + pIndex // + ); + + // + bool isCSMHKBullish = cSMHKBar.IsBullish(); + bool isCSMHKBearish = cSMHKBar.IsBearish(); + + // + bool isPSMHKBullish = pSMHKBar.IsBullish(); + bool isPSMHKBearish = pSMHKBar.IsBearish(); + + // + bool isSMHKSwitchedToBullish = + // + isCSMHKBullish && + isPSMHKBearish + // + ; + + // + bool isSMHKSwitchedToBearish = + // + isCSMHKBearish && + isPSMHKBullish + // + ; + + // + // XTD ... + + // + double cTDBullish = tdHelper.GetBullish(cIndex); + double pTDBullish = tdHelper.GetBullish(pIndex); + + // + double cTDBearish = tdHelper.GetBearish(cIndex); + double pTDBearish = tdHelper.GetBearish(pIndex); + + // + bool isCTDBullish = + // + cTDBullish > cTDBearish + // + ; + + // + bool isCTDBearish = + // + cTDBearish > cTDBullish + // + ; + + // + bool isPTDBullish = + // + pTDBullish > pTDBearish + // + ; + + // + bool isPTDBearish = + // + pTDBearish > pTDBullish + // + ; + + // + bool isTDBullish = isCTDBullish; + bool isTDBearish = isCTDBearish; + bool isTDSwitchedToBullish = + // + isCTDBullish && + !isPTDBullish + // + ; + bool isTDSwitchedToBearsih = + // + isCTDBearish && + !isPTDBearish + // + ; + + // + // XDON ... + + // + XOHCL cBar = cMarket.GetBar(cIndex); + XOHCL pBar = cMarket.GetBar(pIndex); + + // + double cDONUpperOpen = cMarket.don.GetUpperO(cIndex); + double cDONUpperClose = cMarket.don.GetUpperC(cIndex); + double cDONUpperHigh = cMarket.don.GetUpperH(cIndex); + double cDONUpperLow = cMarket.don.GetUpperL(cIndex); + + // + double cDONLowerOpen = cMarket.don.GetLowerO(cIndex); + double cDONLowerClose = cMarket.don.GetLowerC(cIndex); + double cDONLowerHigh = cMarket.don.GetLowerH(cIndex); + double cDONLowerLow = cMarket.don.GetLowerL(cIndex); + + // + double pDONUpperOpen = cMarket.don.GetUpperO(pIndex); + double pDONUpperClose = cMarket.don.GetUpperC(pIndex); + double pDONUpperHigh = cMarket.don.GetUpperH(pIndex); + double pDONUpperLow = cMarket.don.GetUpperL(pIndex); + + // + double pDONLowerOpen = cMarket.don.GetLowerO(pIndex); + double pDONLowerClose = cMarket.don.GetLowerC(pIndex); + double pDONLowerHigh = cMarket.don.GetLowerH(pIndex); + double pDONLowerLow = cMarket.don.GetLowerL(pIndex); + + // + bool isBarCrossedDownDONLowerHigh = + // + cBar.IsBreakDown(pDONLowerHigh) + // + ; + + // + bool isBarCrossedUpDONLowerHigh = + // + cBar.IsBreakUp(pDONLowerHigh) + // + ; + + // + result = + // + isSMHKSwitchedToBullish + // isSMHKSwitchedToBearish + // isBarCrossedUpDONLowerHigh + // + ; + if (result) + { + Print("Salam"); + } + + // + if (result) { + r2r = 2; + sl = cDONLowerHigh; + } + + // + return result;

W;pIilZWkF1bW_NJZfT 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xlh.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xlh.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..3e1086f8506cc725c6ced638ebdee1968b06a5b2 GIT binary patch literal 14786 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xmc.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xmc.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..262a90f33f186481ebbd773db33effcc26b7c511 GIT binary patch literal 17750 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 JLASi=VMsQpeZl|$ literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xmrb.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xmrb.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..23b932e822edc39d651cd4e36ec22fcd4f8d88de GIT binary patch literal 21534 zcmdS71FR@f^Cx(1+qP}nwr$(CZM|#THr};u+t$8sXa1X+-DEbKO*YxnIgP55K3(Xl zUzMl^D~KaNF@gXH00961Aixm_!2dKb?`L(R!JV1_Azri+GoYpZC+5Egvi~#Tzn=g5 zd%Pe30RA%p03ay-i}hdEe9#>t4Ffqi8woPYWq%&5NK! z9~fn`|Ew1Vum^Ae@C0xIumms%umEuR_qj{}4F4uG0L{O9WdOr}RMUTaQ2-kN+kX^E z0F{4d;eRx{f2;q)`Tz6ykHjwjG~f)t1wjAraQ;8!HT~b^rTeFs|9?yPzqSq|0Np=p zGyJa?{V%xcCer*S zD};5|1*UP)KQ~;Cm>2pup6I5<;PbPy!V7;u1{qu__E6tL)dAyFM zu&0deeKM2Z&?@LvkVT{U!t0w)@`UXG&eSqdvJGF$#N)Eq)ZB6V*X=SI zrEfrUJIt-ve&lSNmsfhq)Ju9q2t^(|`$6*FF9-uv2^b&c>IEsmWMh5fvhXYDh^y!N zD3|x7gYsJwFe43ROy{r=B|F_`3S3>4rj;#&NKq1
Sx#m%@rPfYf6qV`?@*^8!m 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 }{aN3|Vr?%mP9cR-_?s650uqJCF3ICdUR zQI_2w@mwbk-T+og(q==mIooG^uQ_%KZPhx&WD#&{F? zuKm)9=_GUftpo~2Z2;phj7@L+yPAIl+b$A=z*numo4mCA7oC>vi@~|%&RwLSSBVy` zQaNL!T{>lY1M@u?M5Zp?t=Z@Hi9l_}{bOa{a?Z6h;{cJF63>_}Oa1YI{kQkO6JDF7 z=U@0+eeBs7Y1}>jRydTT_aN4|t{Jv~S>${sEEw{P(L3l$X0-u7Do7|k32{z7r=A;=OJ6-I0gHuG z3lfg{%CPrP5&98_(7R;D5YQb{Zu2r((DtDP2LtY!fjpX>wy8UH<_IOTWsxO_0|EBitsjZtr$rrB1ibEBnGAYRSP;5OCLqr z6t$0y+nCuhPXoIpLTGCj^ke zm4o|T9bWnsy->!kup45kk6q*|w}~xIdfN-eNCai%%H4N_H~qII}liZHdlC;-i%AsG&|A?_s3mZN$uaD<_uN|HDAfG>Hce6SMG0W&5^?J*{S@**r zqWWmIUjZUsUsNew$C+p86?%-O++w&fwS#mL`efjcq!;jV@2D!fQFdmMoA9|zv!qiD z2^Ue;Kz%p4sR*x>jlo9x*CL4;ch2of>kS(Mq`FrP=p3|-ZakYq7G&bZlAy=ucT*7F>-FWWQpu0vE-Ca?Uvw0pYEfR@X z$PsUbO{0GT-ew4++)|=!s;#8_U6qw))gllci#g0vjVh{9^Q;*|QJEZ?N1)^#!c;wt z4+Q7(=Urmf*2|Et$#vS2SzMc_{7y-fjfr{Vw|bxad%@jSey?xCbNT2_!t9K4{FGtt)`IJ~J?`nau^AE;uLn?(E<{kX0ZpN5Xip*`?e z7V0lat{6EQCg=XS|MRB*K{{qEv^#iz`WG!wEEXE(?09f6zh6iLK(sEil6nQb@vl@ zw5g@;`sZf=Y9omn!+{ucmGxnAN9|>k?MYCvl5lMv()czIZlNCEHKUFbSYr^J;Do*e zr^>(+1ILO{=uat~`oIm=X zHt&EnWd1%!+Eb(CR{045qgy2$cGf@G5Ig?ZE$Fg z*scbA5hKwLGf2rIaLZB(wK%4KzSRR%?35bs^J z4gbI2e<&nsW*h;>+g40{-~3}28CxT{W~mb*rUA23?ch4~!rWv^2!`&}es_;93EB9d z=M3|v8X5}1hk|!!-s88n0i+QnJ={)y17wLxZA0Qn`D8LI@7Z8Ias{Gz zIPvHW1!hEEs;oQl&)+kUW3Zi?ituk?*G%M)IA3!6>d~#r(aHu^2UK!PX|W*qKIIGC#E*6WmQz{V}gWeI&1XP4| z37b2c;Yc8|G{ml}ZX)+)xDg*+cz0Ol4xV-etW^T65UJ||w!K^Q{j!o@yr%8ftp_dT zc>{f+WVC_48X2f1u)m8Z-v6YqHg}1f0I|lKZkt1AVowIpmmaS{ZdEqNXUAe_S|?H- zEW)PMooqW%kCHUXMvU%5Vij+$^+!xMcV*lP=7NUoy@m?n3+2P+xOJ-81s{MbF)YFD z`H19yAEMd#4nH*yt#4kFE}eSRG6(2x@vheX9v~% z;&1))v*=vVHzjT8Z)~4*zq!P z5c@Uln8pU5Chm-0dFehJfgI+`nmO_HKosGErkgY>iyOXN>361kqaR=)N(aO zl91=(cfH#aOJ~0Klqc880@()lVLIlqE%6I|`wtpw{si?nW8O`7-)~Kn6Yp(k1wrM0 z(y6JueQocikj-E`GsIvZ*4>V?^gg=Y&)VlwdEW*thbb#TjSM8hQ(y5$7ynEC`l1|m zW{lz&rsctwbOoZO?Jn0epo*WF3=jgrlRe|qTG-#sCl3DF3U7L5aL2)Q{MP?W+WvGB z_u4u4#vd)(_r{fjrY!!Ie^~BlFrq;T1iG{JuQYtsZk8(P+trm>9`Rh&UXjg!*Zm&> CF>53M literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xpv.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xpv.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..aded4b68a0df5f7578e617e008e42c19890f89a7 GIT binary patch literal 56216 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xsslc.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xsslc.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..acbe642f85bbe73b0941ec4e352dbdbe262d9b7b GIT binary patch literal 14512 zcmdVAV~{3K@Gkm}ZQHhO+p}Zawryi~Y@0i_ZQHhW_jls{PsF(&&i7j#)!mhu(cPI@ z^<-8?i)pZdIs%Fi1wjFX000o+5ESr#v|dg$3$^7)*v*Rl#-w9Aq5p&VZ$SS4CH&9$ z|9y@ZBmnSV2LK=`|A+NIS2jE=FLL~A=4Kp85@tz5aU^#p(LNq&N)p;Vz5SO8r9eJ(SA@n2^F(Ehtu0T}+Hn*QU90c-%a|0q%b z)qiJ^e>A&)(*JS(|J?r5*yW!EoB`YbhJT0i|JK*^f9XsA&o2M}*6{!C9VP(%KW{Vs z--Z4!+ z<=k`PfB4cR_5edoJXySH3>bYIEB1p5EqZp|_^LA!sv|iI}n(!LKK4cMp zGQ6M!-1l(Mg_^peQ$b8nL~O(0M=pQB?8*93X|2iw^G$R->kEByPBo^el_W!rAS8XC ztUI~+5&IESDDhB%(62@7w3Jwdq0eaST;t&%S;k17!CPf02;wC?ZI6xUuz%S&=}HiO zz|H&7;?cs-u|2DXVClNxdp%0ra?~2;I7#(fg3|%qm!1M}Ont5-#r=AKrO90_;vhAH_$0AmqX| z^wY#Yz8p^>xnmm0Kn`NH3(Hr+2^%N{17hX(R1^gBq$&?*ga&}eMefIlVJ!t_uEB{o zzn)V!|L)N&;=rn(>e`80eK&UY$rI_bXPws=rNg~$fSR126>}vheTERGoy*vVdmWgn zNADqgxZd&A!*_vwqTc9v3KWe?JP1(V{oK4gqeS8%?srqqOU)A{APV;fm z+}>d_@wagO2B2c!vWHe4y}{APjBTG<2e4yS{cje3<2(zN5mL^jcU~r#77h{dlSb$2 zEOR1OF$}v@fTrs4Qr&${D6R3_;~K#!uDqYFX~|zGUa!tyeK@ZX_^lIMA-oNBGIm>A z9g$^3!3erDr9>K`l}-M#qdXVPt#8g1{<4bk=6`*iocv4U0)jCv4It)HD$CK}6KvC? zRh>B%lklAAcv+7Me%H?ui$S*kYD<@C7-{UWTiVf6jkj;^Twb3S2ql{kpDnJdRWk&p z-b2_5f*5e6+sE)n{_f~$IEm=X z^9H87BKzUx?v6xquL_5nK<|KqK-xW}9Q{QcaKUX~zDl7wO z{OU&Pd}ptxL9?Trm$e?b|j@;ys{d5!VS)Pygq zNV8eTlepbu#meugXH0Fh z=E0O8DC>?Glw);d*^SCms4&5P(|QmoAa{>URjgW&)4CV0Ntrvmpg;t1gQVO}Bt0F; z*1GVJ!l~sL-Qv$QCKWo3Paa#QAg|*llQ&DT6#~5%r@n2DBHem^D*O*aNg81(uaX}PBRKvbT_Gwy((=)FF1R7eE@QEL@ zN${OFePM29;qkAsHu;}POllh!b_eW;Ra}1fTktRzy^O(2Ur*%;B^)CH7?JSz`LOu2 z#&v9^g{O?3LhEB3RL~Dtn~XG3P+$N)*u$@`*VH1;!C4r>S`o_w|JTe4Y5@V6Zb8P~ zU_XCUWn23fS|6oY{EbQLhPX;i%Ot9VT3{l3{t<7D4MT@ zF~eI;BQ_L^yHypJ8s?$I0Fy*|;Ruq~Jq0N!van;d^Z1VW%?P_A#m+sAj}inNdh~ko zEml8CKKv3A8?OS9+U20R%weq}wNf?nH`|h*Q_mDy24=Y%la7_~JaV5QWzHa=VKpaf zPqXfN23ymX46nJIAIIkG6lQ`%J};c7^)bR0IR5^cW3ca?8){@f!~P4nO*G{}-h!`oCGE5PcIU7xbzS>`q4`o1= z`9Y2|foceSsu_yHfEwI6**q*K$+D%}Pxrfz+UH`x(m;a^gzmRi;?WRKCF^_R@2p_G z#z)YGYa>gU!k}p#pmDPCy5@piWBA{=5{Z1NUxJdFrIx=@y%yrCnLcq4{8KWMc^-yh zYFex;@-n`SSQ8mdefYJBtBHiQ;cozOa8{m1BH6wI%LqRxM@-c&&kwExDXqU!5V=ld zFW^zmVtHWjAu* zCV44Xb;yMht=oww@`U|lw#X{01NR^VNe$Xa^v$7=--TL1nHHs?D>UW~T7ksjH->K8 z>aDP@5AIRVw|=Tl4W=C7m-cK?nMoe+EO%}T&R2xVv057!Ml z99XewUk78S`%1c_`C2N<(oKECs9L&=&{;^Q+VlwC8entzf+56<)HVOxzlq^C72~Ft zUSO)k8OUjnS+4mzbQacDTH~_t-3+jEHvn)L8Qx*QsVqEEj}736fhhjLwnXZk1&U4x=OFYitz_T6ag;eA(*Inh=e>OqBpQ~_F<|5%&MCQb_e7f{VJND3Y$Pq~ z#sU0{WhaZ9j0YC}-aVl4-vpB1e}T9bC-0ISI#%XYIu}$R{~QxgHXNV7j0HMcd5P+t zB~OBNu+Wr~+a%>Cb4jJJ4gM&p^Gl*>9Ffib+=Gy012*v9^pE~WUY4V9MFHvlF8;%){&dEnlCm9fYgs*`E ztc@r%TLAJ5tyt+&12&~ZKPmPsiRV|s!oJI1A_8Jxj8%FkM#v(qCwAJ(^Snp&f_Vjc zRfYBQP@@*&YvkX1f6i)BMFf3@hVPxUZSL~>WOcZFRLhunkoz8ttBvj`G6so5Tab){+6kUE; z;QQ9F!TJZ@gF);@c=VRo9z%LNL%`~!o9NMH7*Xdh50{34qB7c%QuQO4x14a7ud2Y} zsR4F@Gmhj1&+rHxcBvE+VzvWEv^TN(dSZ9&B>>GFuiw4H&56BS9FD#X(UC72>(Hsw z7Bs1DO$;z{?!)%%0*!E%26JW5mcF?fMB27CrjDkfq$$7>pR*h{vxyd!*O=;(uMfN@ zGMv+{e4cQjl661Gfhh>Tg~3nO>Cb|^5bNPm)3^)#6}Ny+)C)uBDL=HT&x#*rjWE$= zn{B;nTK8HPM8`sLZplp3F(Ow%X7wr#3ZS`>Fg$x~aiG#ebU-6<*#(uiMXlhIbn|JL zzLD**nXnkLVXBX04?)h~y{d}ZdfTh{T!Y3^XN%B0rHnxz4VO+jQ!=R{mMN1{qBlU~ zkQTm~LWD;@fbrw?^(M_1Ff0T?>Z7TR?c}7`Gi4Dp1oH5qp%M=zdtPVG9eE8fe}ebr z_t>?$8E_esMFQ7PetSbPzWcNe*nwUi@slJX$7YEixX{~XG)m_a>m|bYBb<~mUL_(iNCB4?{ zXE_X^etBPVW80xm$wU$!=NK=8^m;RQ=b8>E$_}XBv8w~aWYW@*+6qN1z)sEA`kY)G z4^Cc$_07xn7CVm70d-R5U%Z~uWJQjAk}>hr3{fc3dSn_)JOp zKAOP9oti;-4_K#y_Y7>_{zR)vj!pVJ8aNNMpL2%vfrpV}6Ow5B4uT{y1tCy3$Qc&5 zu%%mhoRP-KgNn{c7M$}^8DFhqfm4t(*QF32OE>iRb&1#v$vt>-_#idt070p8IdbyU zzRr0OCM&`u2X85|*ob>{ocviYI$z@qM%|0^iBil_#0c~KXJ!s~%nG^1oNbUDJN8PO zfVnRob_Y9_n zh-{pQ*@AGIX*giLxwO}Dpm(RuD5J`1OW%$q?+GM7- zgnDh@#oF2mOza-H=cY$1hty2;`rS^7MTX+xmu4XI-bmY;?Ea@?+_K=8P;EpE)8UI` zK42H9(7|kFMlC-RYPx}iwX~s=v3B9iUjXU;ZFB@{cGv*aH#8Tw=t4_p2R$=HHU9)a z*Ij}7rwy4x)%cJjORv<9SQjsbs+bhj7qO80IeGRZ=ew(W{>IJqGOz$dKGL;KBvJTg zxMQ*6vaz%ws?@&OHQz8ZSIRBXSXFfM&vtb<@Gtp7jT}(3{6ksOfKVyB3<_ByzYk2= zE1(hkP;G0Se>@4JHLm3v zuVVdIllC7pQpMgLPDr|y>s0v}iuIE(p&T-qQ^gkN@sr6Mh=@UfBVGTRziCvgxZ~+l zWXu=Lx^ppNx1y76HWi*)6804O;6!)UZ6Rojb0x{SNjzrL=5R-y*&YfBE}1|gEk@t{ zwI2q1f>}3XD!>%)VHHy><+5i%fQ>|R%>fEn`qu4t&VcePMY3DkV1x0*euQp) zJq;IH+iJ;z@HuC3_eG|_lbC>xj?BgGvD#n|tFsOCz=v%rhwv)&;I4@O9$x!g8u%?L z&xoZZ!sIx`>xtjkK7ivFJYOHb%Y!0V5B1e-WE(IvVm~NB48GJ}{+19dZ--FRVc{+- z0#I~K;dbo<`GM1|L}OaZ;e7A~aM?O>7WVw6Pr;zD!g@e|zK2vtcCSNwn%(51T)7X+ zjS-A|f8Pdv81-d(N$X6vg*zE>Z=zOA9!w?UcQksf!QX8JY0y<9QWis@*v$0#=LZ^) znwPSAa1JclX;~QD4%n(p&=_Ir$K+W`pl0=LdQye3{XH5xwfV`g3>00lPc#BE|?}@u21&@#tC} z+FL8y2aT%`$v(U}tRn#ytR-GdCgGjZsQcIfdQ^Dbe~wneUYimmU4aFz0;rehZ^+m9 z&>BI{-ITs?hnlUG|bmx7k1 zGU(LNpxX;78uIAxRq2j8D92H6Wa>+4ZKhw(o>7FM=(JU30dy}fVf?J0Spq`o@|LUqs@nK^^6)!%r!)ar zl=?+kz&h;8_ROM(w>^$hRg#!iZIE1--j;KJs=24rWTqJm8A{xk)ghv*m0cgagk`e~ zq94DYr~lsh5#TKAJEMNxN1N+K?Zku5>Zcco{bJa}(zM~p*nc?d%F;!>VgH!!c{M1D zH9c*G2iv&N=8O>6f%Tb8YlaWW`U3p5F|C%**5r}{6@^S1MhXw?3m(YVOX!CTR}1oF z>RX^!)Cng6>KTWKM2*>wP>Hg&m1BWX`Wf)a5Xhrn<*vXVa4FV{+H?>kDK&K$)CZ7_! zp@EWfE-ZJc^E&X%E%%2Iw&`NT3_`+^s_*$El6!H?A*VZO^SL5)uPWZ<266O~Vy#KGP6(G<6PpKBuSs z+wllYDq31u08iMY9|%90q}EUbycQlD{^$eM^`>qX`2MtLEO*lwh!#qlGlK?McF%*H`9W2#RZoaPiFh(tZwSjmG>!afJ;a2C z0nX+r@Y=Mwg1E}~YQoc06(QqQJ{ll*F}hhbE68gav-QicS{J8o{+Utz|v^XrOCC)a1NHb_Pt zr0*Dpwdi}`e+hBOMS1+pbI@y&BoU&gl)G=b3PF*oK~s|LjjLc7Ex%$jODR|weninF zhX!X)*UB4X6FJ_6vr>&9iQ8oT!!^`GpbA@oy`WYQ>Sty;Rg&;) zS_4;0Xq*fYq75GwAv|yRG>|pN6cu`0wR-VrrL>>FBAh7{uao2MXuAv&qps9v`M`vxiBs?u9C?__z>~k%M~M)iVK8oH z%$UCf*OqlOfM}7dd$9x!^2+TJ$3<+AP6acSm#mzr#Tm*ml5pmKZ&-1IF74pS4VMmz z#!p~5 z7h_kA@9yKke0r9InDmfi#nLiafbJM`eTT`7Q-nR>WhZMPxIu_7grG+-cp zArOJjI|fvxJqZN%0!$ar8dSv&vQP6oYXf(6{fpKS?+g)Tbq*pc2!cM))2V4{u{)ly zI~3RyGr_~g)65^rm{uuH)z>(y1K5~>t-b16g7oC;EvuOJ?SNdMHl4W=r8K5f*x6phNj@35E*;dF<^c2wj0b; zDD#d4*+>-j*j}N4)4=%c;4uXoOjtVSP->Sc+|Fzqb`H4;q}-zL6?w9)PIt&Ca%2UX zKEZ06ngcd$ueB!yxs<3bjg`nr;z_N5>sgR7h?m;jwK$hJ%(LkvsDDQ_N_pI?^_>w&XBiLE^I_@3W^1 zM+lvJQ3_qE4T-c7hFAH1P?f@azFOej-7Y^2)DqFs4weUw;Wc#0xRk!*;=xDC$U^Bq zJplxO3^$P^(BTGU)<9paW){C1oiUE__thF~x(#;{w1B-%P34Gkgw)8C?Es3yeF4Ou zw7qvs1$%O}HTC=P>QK|cOmcYZxiwx#Bb5W{lZi%4y~8EjIIKf=!r0wGpAM^@uUh%U za#AQryQ^>{@*S)z6Y^>lXU#_`2kerK_M8`Q>BG(W)|W&HHrx}e9~OZN21;I+2}3c4 zDag=xaF(raSd{jXyn9qLF$nbfcnF%qfGh}BmW@6l5cvoe`J8EXF0%ZPmud61aMMCS zwV^!%Kxbb!9(=n6!@i(?=@N?K^nsnW@Eb{|0Etq`cR3y2UB4Rj&~1h0eGW~`b>x-K zA%6~BCO#E=oT&${ca%YV&72Kt5;>Nef2rO5Nva#hDBk~d&TH=lHi-u0tTX4rcce=8 zgJIPH5LNc)MmvPQw|n-!cIs~-lQ47kD4T~4SMX-UWI*sLMBWzgX=r8}fHS;3Ns`UCMNS-`uCp zzHJ-JK3_3DSPRUZi3hp%UY=<{_uL&zf08cWRt&q<-5n!y?n1LIwa_?orJL*6Sh*_K ze^Txq<}x#Hk{#*?$a6ig2VF*;LSaAP;@e7>9caflT(ttOQ-$u!3a3R$tFv!mz2hX~ zFI2KVfipB+Mo)yB-64Rf(hqPQdk^h* zaOt68Hr=QA5TdXYf?d68@zXN^U2%Xk` zt6GGcGk29?&2~M;O51B;d!?`lA_U2iN{$%Z5Cn?Ai*dL&Cz_wEAM<||lY`U07$-W;-l@CCCXc(3`NB6z z((M<;FEMr^6Q6QJzTc3Mk+fl}9hEKfmc}ghr{3B!kFYyj#VI768jB5i$k1w^>-Xup zwSV(Bu#Xk(PtmP}%Qj!Y^{hb3qSQh{>8+$!AJQ@zR0*#$tS%V_-P;#S#OJEonzJ^0g>eViw=EdPm zJQ788abpJ-ufkmNRECltN>!rjQ}WX%DGc(n(Q^8%(Dho)CR7m1YZW*ZN3a4qC#=jgOUxXt5BsdHvPB|OTuh|O&7@*$BE!}~+# zr*GHC$L}@4(w_|3NDV@}oPUubrNeTxj9KxOWC~a6N3QStY#-fQ01l04cCE;sJJz|P z6U5FTeS{tM5_M@+{7rdj=ONkFfrZ*i^}r^gJw60l>jTUga9mP3g%#&&ty}pBe@{5dh8oD4qdcYCE;` z!10v|+7Yhq+nniSq?OQR6gOq40AB6PLRfgBPxZP}#hFxBiU z?$F1-&MQ*89vcU{6om@5oY_8#2{MY!=_9>4jZz4fdh)@sf$@1rTZzs`Crt9->i=4m*1EovhBz@(36^mr!W}`DCW7#590F7J$NF z#*sruD1j%);O+tR>$42ONiFDgra}}6#O>8+ar8;wb9Fx2 zOH?Y@vao65mN3511-rth-cakvuHZiAP$emc&;6|_mB{_@-XC{U+yTzlBa7`{M7Nv8%yUk9<3z0l zSKo73&G!so7);ZxR>A+Re|zN4KQ_SM$|)Vq3w~8TUp{>(!navZX#c%`g-NoE-fV}O zuaoUqq(+vt$~E`)Ci3E*xlEAMjW3O`DU?rVi9!W)>O!APpbmb0^1(yTQ0e#dN8T(# zxT`t*VoE-##cqYC0ac6IM{-9PZmvWh{@qRaz|_U|Kaa=f`sSCS)Rnb+)yiMaD(4;I_W@O+`AG=XqE7*zy{{u zxV&~z+MQP~$Ajd9Fh;ni=Bo=9op(iM59E`LsHS5dON?2M<~nU4b|KM;SL*t zGI9Da1<&z$o9U%}joU?KoLMcj_6%V-N_HXwuZwEzu^b=#Mr)c^Spf7oZ4xxDWpZEHR0|NgOJkk_e7*GX%7 z?M4jb1f{K_z8PuNO>WdUrMTVRkHlVY<@S4CFHg{{kUCuy{==4K<<0Dgru;Is^X6}k z&C*^+JU{7x{lYXdfPulwuA1DJhzze%yy#64kjDe(7bpF1{u8K`+UaQWscw3(|<|522CS$_r`ouuMgG1 zwZF?k30oS#>sID&<^T)|^2tZ2q6q1dm=`)W^bxr~;XRze8kBmsGn~uaXL1qbb16_a zyxbh8+5hm533#~a=KCV=32YC3T=Zikt?PKQFqz9fTiB}HMA;Fu#*Vc$6|Nx=e1>ua z;R9SZ?YQADyi+HfK-iCTSR@QO!Aq*|aqSxQfAI&{1M$&` z=hlk@a_UkhJ3`JWVKHNr>$dYh{Ik;s8=N35<+li zp4h}vrOWt-gJ8p!$uf#8Jg$u)-1@A+{4U>#LtWaqK9W`@TFL*m)LG4^INC`0m0lZ| z+Va2n^VD2GW_?iQZA#yv^?ImS3S^;WEtet^Aczi0yxI$dJ=(1T@|*W~;3YP8Zx0-R zuN9%Owuoh&A@ic>2)nJI?>u!V8q&e)9|-WI`8Ef;l1AZ+vjw-X_kD=AziP35syi`p zU=4TT*!mCvV=2<6fFFm2!+A6{N#+s?cs^5Q$ias@H8SR^%6w(^;(XwL6OyOsNNXupvpuGjc-;1FglyV`A9~1roBu; z^JybVq#VBg@;{0=9a{=JXo(`Pqo4h8H2T!&SU$0{_Z25d!{+Ao#d{V*riQ9J5hu(+ zJigTm92yAzZ1{#Vqv~0OQBT=s6`r(z`R{@6&hdiO-jE1vpA5umcIPe&{y}8vMg5K< z#DW)fi+xv>azvA6U@s^6RtR;kDNYgINlTXLeIg@n#7+=8&Vs85VSxx1jaaz7oLNQ! z@qDL&huX0Zjy*I3l|x&s?^K> zS%3eaT`a*Eqxh6+-m#xriR^SG+pmP0kz)sm^_&Bj70|7vBgHYS2) z--CeSjYD0E=l|lbgU%>{Fd6!yLyK~JOHB8wp7_q zoZqzBs)P*Ol}7!In(_PxGEu;{rSic2wao4}Z4q`HgT}zuTJ<*j9$w>!RcG<0?ui&b z4HN6S)KsLSP72#DXqEsnkF>6f8AU3)q6IB*28G{N4gFmhGL^@;R?_y@=9m|%_vF;B+8MK$wU>TK2{-ySt@U+g?2ZN#}Dd z{`G%p&%E|$c#`Iat%HXi9F#f!W{7j(&z;A4BlC?W_Z$4Cr}6jrhks8b4=yYoB}*th z*3lwpB`pP?hJC3M6iyFL7g-75+MO3NQKSn=Fjrt92b@w@x|p=UoMo@g`Wya6n!9(| zl@Vo(CC<%SKjVdqVJ{iv)zZzVtv=FNEQ>q!qUWc-{ zL!Uzi6H!8sHa3*vZcz0F?1>u70}$7gH}%@8a!*;j<00-mQy=r#}<6w2l zTY&dc$f1C1&YAx={!AZrb?Q}1Jo28`<^h7&6}`%VIXwHTa1L;#EYJ z?X{}E%9t168we2XQpqAD5k-uBP>$5irYRNcvgWN@DyU`y`AR4dfG3{B>zmFH4odp8 zC=htKp-Iulmsj|{bVE3RXL=$l!jwZ&lYO=>k6ny)sZR`Fgul?tRat=P&t=KE$*)R) zjo3dP)QkcB;Zxpb7~l2dHQLO0r_TF=p@#%9&gMBHzN#CA23jh<8y@uajb5l5_p-(V zjb{+b$ce_NVK)a8Ad_J$)e^lUt#o-Iz!Uz@^1E7L*vWxy`GVfvDBe?M6)zxol%_s6Nms&BedY1-3Sj9Ee$=)Oq&s|8(-uY4lOv zydQ`teQPpU4=~i)xzDN!FJ~xqYS9FYLH*nR$qj}qnyzz-x+9Xoz)?wINR5x}greZj zdI*x_cG&rwp@2%}tTX7{p-RA`*8i0;$mJQwAct%k;q;mQ(*C#qVtG%|j=-B(yj`n? zpsgfb`mr#U8BboP(S9PKRvraC6-Q{|kJgbiFMbJ^y+Z)uNdj&Qt)we=`1=cZ1V$l( zQ=va>-h7o?*b|-t3V}ifO=fgrD;$Y%+KZnoyUQlf1Pxd^Ym?6423-shxv@n~FQ01? zt&$wdHI6n=0ZLjYcu!Win%&-$JcmYGGw3^FctfVAt^Lt-EG&e19vN>)3f5jggnk1?`or$d4QI$i0G8}md*i# zoE;V}Dk!rcq2NOAsShsNn!OZuS%bTqJv5v^=^UrpJB%V2URj^8WtwOoVII?WKrn}! z*0-8c-10AuzcgNUOv&tuChkzabJ{%QcP#;GnmHrO#ItQRwy4CEaxWYpTLb6Rh|=k# zXr1$JU0#Kg4UwJ%YC#kVaS%^cDwwN7k};su*`e|qUdQwNsWW31Vg1jxYG9;exVr60 zs-#C{rFvf);~#dZ=x2ARQxDrpbjych5K6#BJXD}jrhXKC+s6lmNaHQDel@3_IZ$+E z;CC)m|EvCBKI8o^eW)IVp6=U~E$ZHn;6G+Hj6A5ez>8N!&RU3PRhr)#)TKs|@*sRo z4QuvpR(;%G@XXVgN+KAvs+1+gcw!p(g6zG>L{0NDooOM`iGT7w3`43_j+Dhp%HVGC z$)ua4q?!WLhUmtheNb2#h$cI+spZWwnE(0toV+N({V7j@heXwSHmG>+;3$2wUzL^q zM<6|@#PW9S&CpGnZ_(vY?VM88oDdD?i;IgQC#v{!kfwQvBK37-SZ-Ewa2>w z2)l V+BK2#+V4^_`N22R@{fjq{|BwvvDg3r literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xstr.ex5 b/MQLTestWorkspace/BKPS/14030306 copy/Indicators/x-saherelm.xstr.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..1fe0f15715313d6c91b3974f5dd9a9eae86811a4 GIT binary patch literal 12730 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

1okFSeRPOd}3&DMD%0|f0n9i?sVl`ny^to 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 z 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�jC9td38sigrlOq{rfb$RQ?(( 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