//+------------------------------------------------------------------+ //| UnitTests.mq5 | //| Unit Tests for Package barhelper | //| Organization: douglasrechia | //+------------------------------------------------------------------+ #property copyright "Douglas Rechia" #property link "https://knitpkg.dev" #property description "" #property description "Version: 1.0.0" #property description "" #property description "Description: Unit tests for package barhelper" #property description "Organization: douglasrechia" #property description "Author: Douglas Rechia" #property description "License: MIT" #property description "" #property description "Powered by KnitPkg for MetaTrader" #property description "https://knitpkg.dev" // Include the headers under test #include "../knitpkg/include/douglasrechia/barhelper/Cross.mqh" //+------------------------------------------------------------------+ //| Tests CrossUp when series1 crosses up series2 | //+------------------------------------------------------------------+ bool TestBasicScenario1() { double array2[] = {0.99, 0.98, 1.00, 1.00, 1.03, 1.04, 1.02}; double array1[] = {1.00, 1.01, 1.01, 1.01, 1.02, 1.01, 1.03}; bool expected[] = {false, false, false, false, false, false, true}; douglasrechia::TimeSeriesArray series1(array1, -1, -1, false); douglasrechia::TimeSeriesArray series2(array2, -1, -1, false); for(int i=5;i>=0;i--) { // expected index is in the inverse order because TimeSeries index 0 is the latest element if(douglasrechia::CrossUp(series1, series2, i) != expected[ArraySize(expected)-i-1]) { Print(StringFormat("Fail at shift %d", i)); return false; } } return true; } //+------------------------------------------------------------------+ //| Tests CrossUp when series2 crosses up series1 | //+------------------------------------------------------------------+ bool TestBasicScenario2() { double array1[] = {1.00, 1.01, 1.01, 1.01, 1.02, 1.01, 1.03}; double array2[] = {0.99, 0.98, 1.00, 1.00, 1.03, 1.04, 1.02}; bool expected[] = {false, false, false, false, true, false, false}; douglasrechia::TimeSeriesArray series1(array1, -1, -1, false); douglasrechia::TimeSeriesArray series2(array2, -1, -1, false); for(int i=5;i>=0;i--) { // expected index is in the inverse order because TimeSeries index 0 is the latest element if(douglasrechia::CrossUp(series2, series1, i) != expected[ArraySize(expected)-i-1]) { Print(StringFormat("Fail at shift %d", i)); return false; } } return true; } //+------------------------------------------------------------------+ //| Tests CrossUp returns false when shift is out of bounds | //+------------------------------------------------------------------+ bool TestShiftOutOfBounds() { double array1[] = {1.00, 1.01, 1.01, 1.01, 1.02, 1.01, 1.03}; double array2[] = {1.00, 1.03, 1.04, 1.02}; douglasrechia::TimeSeriesArray series1(array1, -1, -1, false); douglasrechia::TimeSeriesArray series2(array2, -1, -1, false); for(int i=3;i<10;i++) if(douglasrechia::CrossUp(series2, series1, i) != false) { Print(StringFormat("Fail at shift %d", i)); return false; } for(int i=-1;i>-5;i--) if(douglasrechia::CrossUp(series2, series1, i) != false) { Print(StringFormat("Fail at shift %d", i)); return false; } return true; } //+------------------------------------------------------------------+ //| Tests Cross detects crossings in either direction | //+------------------------------------------------------------------+ bool TestCross() { double array1[] = {1.00, 1.01, 1.01, 1.01, 1.02, 1.01, 1.03}; double array2[] = {0.99, 0.98, 1.00, 1.00, 1.03, 1.04, 1.02}; bool expected[] = {false, false, false, false, true, false, true}; douglasrechia::TimeSeriesArray series1(array1, -1, -1, false); douglasrechia::TimeSeriesArray series2(array2, -1, -1, false); for(int i=5;i>=0;i--) { // expected index is in the inverse order because TimeSeries index 0 is the latest element if(douglasrechia::Cross(series2, series1, i) != expected[ArraySize(expected)-i-1]) { Print(StringFormat("Fail at shift %d", i)); return false; } } return true; } //+------------------------------------------------------------------+ //| DoTests | //+------------------------------------------------------------------+ void DoTests(int &testsPerformed,int &testsPassed) { string testName=""; //--- TestBasicScenario1 testsPerformed++; testName="TestBasicScenario1"; if(TestBasicScenario1()) { testsPassed++; PrintFormat("%s pass",testName); } else PrintFormat("%s failed",testName); //--- testsPerformed++; testName="TestBasicScenario2"; if(TestBasicScenario2()) { testsPassed++; PrintFormat("%s pass",testName); } else PrintFormat("%s failed",testName); //--- testsPerformed++; testName="TestShiftOutOfBounds"; if(TestShiftOutOfBounds()) { testsPassed++; PrintFormat("%s pass",testName); } else PrintFormat("%s failed",testName); //--- testsPerformed++; testName="TestCross"; if(TestCross()) { testsPassed++; PrintFormat("%s pass",testName); } else PrintFormat("%s failed",testName); } //+------------------------------------------------------------------+ //| UnitTests() | //+------------------------------------------------------------------+ void UnitTests(const string packageName) { PrintFormat("Unit tests for Package %s\n",packageName); //--- initial values int testsPerformed=0; int testsPassed=0; //--- test distributions DoTests(testsPerformed,testsPassed); //--- print statistics PrintFormat("\n%d of %d passed",testsPassed,testsPerformed); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { UnitTests("barhelper"); } //+------------------------------------------------------------------+