MTF Bollinger Band indicator

Indicators coded by community members
Message
Author
imamushroom
Posts: 33
Joined: Wed Jan 20, 2016 2:52 pm

MTF Bollinger Band indicator

#1 Postby imamushroom » Sat Feb 18, 2017 12:23 pm

Hi,

This is my first indicator and I'm having problems updating the Styles and parameters when the parameters have changed. Please could someone help finish off this indicator. I believe the core functionality is working.

My code is this:

Code: Select all

// MTF_Bands.cpp : Defines the exported functions for the DLL application.
//
// (c) Andrew Leach 2017
// License: Freeware

#include "stdafx.h"

//---------------------------------------------------------------------------
// MTF Bollinger Band indicator
//---------------------------------------------------------------------------

#include "stdafx.h"
#include <windows.h>
#include "IndicatorInterfaceUnit.h"
#include "TechnicalFunctions.h"
#include <math.h>
#include <limits.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <numeric>
#include <functional>
#include <iostream>
#include <ctime>
#include <iomanip>
#include <string>

// External variables
int Tf;
int MaPeriod;
double Deviation;
int Shift;
TPriceType ApplyTo;

string iName = "MTF_Bands";

// Buffers
TIndexBuffer BandsUpper, BandsMain, BandsLower, StdDev;

//---------------------------------------------------------------------------
// Initialize indicator
//---------------------------------------------------------------------------
EXPORT void __stdcall Init()
{
   // define properties
   IndicatorShortName("MTF_Bands");
   SetOutputWindow(ow_ChartWindow);

   // register options
   AddSeparator("Common");
   
   Tf = 0;
   RegOption("Timeframe", ot_TimeFrame, &Tf);
   SetOptionRange("Timeframe", 0, MaxInt);

   MaPeriod = 20;
   RegOption("Period", ot_Integer, &MaPeriod);
   SetOptionRange("Period", 2, MaxInt);
   
   Deviation = 2.0;
   RegOption("Deviation", ot_Double, &Deviation);
   SetOptionRange("Deviation", 0, DBL_MAX);

   Shift = 0;
   RegOption("Shift", ot_Integer, &Shift);
   SetOptionRange("Shift", 2, MaxInt);

   ApplyTo = pt_Close;
   RegOption("Applied To", ot_EnumType, &ApplyTo);
   AddOptionValue("Applied To", "Close");
   AddOptionValue("Applied To", "Open");
   AddOptionValue("Applied To", "High");
   AddOptionValue("Applied To", "Low");
   AddOptionValue("Applied To", "Median");
   AddOptionValue("Applied To", "Typical");
   AddOptionValue("Applied To", "Weighted");

   // create buffers
   BandsUpper = CreateIndexBuffer();
   BandsMain = CreateIndexBuffer();
   BandsLower = CreateIndexBuffer();
   StdDev = CreateIndexBuffer();

   IndicatorBuffers(4);
   SetIndexBuffer(0, BandsUpper);
   SetIndexBuffer(1, BandsMain);
   SetIndexBuffer(2, BandsLower);
   SetIndexBuffer(3, StdDev);
}

EXPORT void __stdcall OnParamsChange()
{
   RegOption("Timeframe", ot_TimeFrame, &Tf);

   RegOption("Period", ot_Integer, &MaPeriod);

   RegOption("Deviation", ot_Double, &Deviation);

   RegOption("Shift", ot_Integer, &Shift);

   ApplyTo = pt_Close;

   string ApplyToStr;

   switch (ApplyTo) {
      case 0: ApplyToStr = "C"; break;
      case 1: ApplyToStr = "O"; break;
      case 2: ApplyToStr = "H"; break;
      case 3: ApplyToStr = "L"; break;
      case 4: ApplyToStr = "M"; break;
      case 5: ApplyToStr = "T"; break;
      case 6: ApplyToStr = "W"; break;
   }

   string band = "Upper";
   string str = iName + "_(" + band + "_" + to_string(MaPeriod) + ApplyToStr + ")";

   SetIndexStyle(0, ds_Line, ot_LineStyle, OBJPROP_WIDTH, ot_Color);
   SetIndexLabel(0, str);

   band = "Main";
   str = iName + "_(" + band + "_" + to_string(MaPeriod) + ApplyToStr + ")";

   SetIndexStyle(1, ds_Line, psDot, 1, clRed);
   SetIndexLabel(1, str);

   band = "Lower";
   str = iName + "_("  + band + "_" + to_string(MaPeriod) + ApplyToStr + ")";

   SetIndexStyle(2, ds_Line, psDot, 1, clRed);
   SetIndexLabel(2, str);

   band = "StdDev";
   str = iName + "_(" + band + "_" + to_string(MaPeriod) + ApplyToStr + ")";

   SetIndexStyle(3, ds_None, psClear, 0, clRed);
   SetIndexLabel(3, str);
}

//---------------------------------------------------------------------------
// Calculate requested bar
//---------------------------------------------------------------------------
EXPORT void __stdcall Calculate(int index)
{
   int i,y;
   double p;

   vector<double> v(MaPeriod);

#if _DEBUG
   string str = " MaPeriod = " + to_string(MaPeriod);
   Print(str);
#endif

   for (i = (MaPeriod-1); i >= 0; i--)
   {
      y = iBarShift(Symbol(), Tf, iTime(Symbol(), Timeframe(), (index + (i * Tf))), false);


      switch (ApplyTo)
      {
         case 0: p = iClose(Symbol(), Tf, (y + Shift)); break;
         case 1: p = iOpen(Symbol(),Tf,(y + Shift)); break;
         case 2: p = iHigh(Symbol(), Tf, (y + Shift)); break;
         case 3: p = iLow(Symbol(), Tf, (y + Shift)); break;
         case 4: p = (iHigh(Symbol(), Tf, (y + Shift)) + iLow(Symbol(), Tf, (y + Shift))) / 2; break;
         case 5: p = (iHigh(Symbol(), Tf, (y + Shift)) + iLow(Symbol(), Tf, (y + Shift)) + iClose(Symbol(), Tf, (y + Shift))) / 3; break;
         case 6: p = (iHigh(Symbol(), Tf, (y + Shift)) + iLow(Symbol(), Tf, (y + Shift)) + (iClose(Symbol(), Tf, (y + Shift)) * 2)) / 4; break;
      }

      v.at(i) = p;

#if _DEBUG
      string str = "index = " + std::to_string(index) + " i = " + std::to_string(i) + " y = " + std::to_string(y) + " size of v = " + to_string(v.size()) + " v = " + to_string(v.at(i));
      Print(str);
#endif
   }

   double sum = accumulate(v.begin(), v.end(), 0.0);
   double mean = sum / v.size();

#if _DEBUG
   str = to_string(index) + " : sum = " + to_string(sum) + " mean = " + to_string(mean) + " size of v = " + to_string(v.size());
   Print(str);
#endif

   BandsMain[index] = mean;

   vector<double> d(v.size());

   transform(v.begin(), v.end(), d.begin(), [mean](double x) { return x - mean; });
   double sq_sum = inner_product(d.begin(), d.end(), d.begin(), 0.0);
   double stdev = sqrt(sq_sum / (v.size()));

#if _DEBUG
   str = to_string(index) + " : sq_sum = " + to_string(sq_sum) + " stdev = " + to_string(stdev);
   Print(str);
#endif

   BandsUpper[index] = mean + (Deviation * stdev);
   BandsLower[index] = mean - (Deviation * stdev);
   StdDev[index] = Deviation * stdev;

   d.erase(d.begin(), d.end());
   v.erase(v.begin(), v.end());
}


Thanks in advance.

FX Helper
Posts: 1477
Joined: Mon Apr 01, 2013 3:55 am

Re: MTF Bollinger Band indicator

#2 Postby FX Helper » Fri Feb 24, 2017 5:12 am

Hello,

As far as I know RegOption, SetIndexStyle, SetIndexLabel should be in the Init function only.

Probably this causes the problem.

Please try to move them and check if this works.

Stonev
Posts: 204
Joined: Thu Jan 28, 2010 2:20 pm

Re: MTF Bollinger Band indicator

#3 Postby Stonev » Tue Mar 07, 2017 9:23 am

Hello,
i have FT2/FT3 version of this indicator,
i coding in Delphi, so can not help with your code
but i can share dll file if you steel need this indicator

Regards,
Alexey
Coding & Converting

imamushroom
Posts: 33
Joined: Wed Jan 20, 2016 2:52 pm

Re: MTF Bollinger Band indicator

#4 Postby imamushroom » Mon Jul 24, 2017 12:43 pm

Hi,

I managed to get it working and I promised the code so here it is:

Code: Select all

// MTF_Garch.cpp : Defines the exported functions for the DLL application.
//
// (c) Andrew Leach 2017
// License: Freeware

//---------------------------------------------------------------------------
// MTF Bollinger Band indicator
//---------------------------------------------------------------------------

#include "stdafx.h"
#include <windows.h>
#include "IndicatorInterfaceUnit.h"
#include "TechnicalFunctions.h"
#include <math.h>
#include <limits.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <numeric>
#include <functional>
#include <iostream>
#include <ctime>
#include <iomanip>
#include <string>
#include <cstring>

// External variables
int Tf;
int MaPeriod;
double Deviation;
int Shift;
TPriceType ApplyTo;

TPenStyle UpperStyle = psDot;
int UpperWidth = 1;
TColor UpperColour = clRed;

TPenStyle MainStyle = psDot;
int MainWidth = 1;
TColor MainColour = clRed;

TPenStyle LowerStyle = psDot;
int LowerWidth = 1;
TColor LowerColour = clRed;

string iName = "MTF_Bands";

// Buffers
TIndexBuffer BandsUpper, BandsMain, BandsLower, StdDev;

//---------------------------------------------------------------------------
// Initialize indicator
//---------------------------------------------------------------------------
EXPORT void __stdcall Init()
{
   // define properties
   IndicatorShortName("MTF_Bands");
   SetOutputWindow(ow_ChartWindow);

   // register options
   AddSeparator("Common");
   
   Tf = 1;
   RegOption("Timeframe", ot_TimeFrame, &Tf);
   SetOptionRange("Timeframe", 1, 8);

   MaPeriod = 20;
   RegOption("Period", ot_Integer, &MaPeriod);
   SetOptionRange("Period", 2, MaxInt);
   
   Deviation = 2.0;
   RegOption("Deviation", ot_Double, &Deviation);
   SetOptionRange("Deviation", 0, DBL_MAX);

   Shift = 0;
   RegOption("Shift", ot_Integer, &Shift);
   SetOptionRange("Shift", 2, MaxInt);

   ApplyTo = pt_Close;
   RegOption("Applied To", ot_EnumType, &ApplyTo);
   AddOptionValue("Applied To", "Close");
   AddOptionValue("Applied To", "Open");
   AddOptionValue("Applied To", "High");
   AddOptionValue("Applied To", "Low");
   AddOptionValue("Applied To", "Median");
   AddOptionValue("Applied To", "Typical");
   AddOptionValue("Applied To", "Weighted");

   // create buffers
   BandsUpper = CreateIndexBuffer();
   BandsMain = CreateIndexBuffer();
   BandsLower = CreateIndexBuffer();
   StdDev = CreateIndexBuffer();

   IndicatorBuffers(4);
   SetIndexBuffer(0, BandsUpper);
   SetIndexBuffer(1, BandsMain);
   SetIndexBuffer(2, BandsLower);
   SetIndexBuffer(3, StdDev);

   string ApplyToStr;

   switch (ApplyTo) {
   case 0: ApplyToStr = "C"; break;
   case 1: ApplyToStr = "O"; break;
   case 2: ApplyToStr = "H"; break;
   case 3: ApplyToStr = "L"; break;
   case 4: ApplyToStr = "M"; break;
   case 5: ApplyToStr = "T"; break;
   case 6: ApplyToStr = "W"; break;
   }

   string  band = "Upper";
   string str = iName + "_( " + band + " )";

   PChar cStrU = NULL;
   std::vector<char> cstrU(str.c_str(), str.c_str() + str.size() + 1);

   SetIndexLabel(0, str);
   SetIndexStyle(0, ds_Line, UpperStyle, UpperWidth, UpperColour);

   band = "Main";
   str = iName + "_( " + band + " )";

   PChar cStrM = NULL;
   std::vector<char> cstrM(str.c_str(), str.c_str() + str.size() + 1);

   SetIndexLabel(1, str);
   SetIndexStyle(1, ds_Line, MainStyle, MainWidth, MainColour);

   band = "Lower";
   str = iName + "_( " + band + " )";

   PChar cStrL = NULL;
   std::vector<char> cstrL(str.c_str(), str.c_str() + str.size() + 1);

   SetIndexLabel(2, str);
   SetIndexStyle(2, ds_Line, LowerStyle, LowerWidth, LowerColour);

   band = "StdDev";
   str = iName + "_( " + band + " )";

   PChar cStrS = NULL;
   std::vector<char> cstrS(str.c_str(), str.c_str() + str.size() + 1);

   SetIndexLabel(3, str);
   SetIndexStyle(3, ds_None, psClear, 0, clWhite);
}

EXPORT void __stdcall OnParamsChange()
{
   SetIndexStyle(0, ds_Line, UpperStyle, UpperWidth, UpperColour);
   SetIndexStyle(1, ds_Line, MainStyle, MainWidth, MainColour);
   SetIndexStyle(2, ds_Line, LowerStyle, LowerWidth, LowerColour);
   SetIndexStyle(3, ds_None, psClear, 0, clWhite);
}

EXPORT void __stdcall Done()
{

}

//---------------------------------------------------------------------------
// Calculate requested bar
//---------------------------------------------------------------------------
EXPORT void __stdcall Calculate(int index)
{
   int i,y;
   double p;

   std::vector<double> v(MaPeriod);

#if _DEBUG
   string str = " MaPeriod = " + to_string(MaPeriod);
   Print(str);
#endif

   for (i = (MaPeriod-1); i >= 0; i--)
   {
      y = iBarShift(Symbol(), Tf, iTime(Symbol(), Timeframe(), (index + (i * Tf))), false);

      switch (ApplyTo)
      {
         case 0: p = iClose(Symbol(), Tf, (y + Shift)); break;
         case 1: p = iOpen(Symbol(),Tf,(y + Shift)); break;
         case 2: p = iHigh(Symbol(), Tf, (y + Shift)); break;
         case 3: p = iLow(Symbol(), Tf, (y + Shift)); break;
         case 4: p = (iHigh(Symbol(), Tf, (y + Shift)) + iLow(Symbol(), Tf, (y + Shift))) / 2; break;
         case 5: p = (iHigh(Symbol(), Tf, (y + Shift)) + iLow(Symbol(), Tf, (y + Shift)) + iClose(Symbol(), Tf, (y + Shift))) / 3; break;
         case 6: p = (iHigh(Symbol(), Tf, (y + Shift)) + iLow(Symbol(), Tf, (y + Shift)) + (iClose(Symbol(), Tf, (y + Shift)) * 2)) / 4; break;
      }

      v.at(i) = p;

#if _DEBUG
      string str = "index = " + std::to_string(index) + " i = " + std::to_string(i) + " y = " + std::to_string(y) + " size of v = " + to_string(v.size()) + " v = " + to_string(v.at(i));
      Print(str);
#endif
   }

   double sum = accumulate(v.begin(), v.end(), 0.0);
   double mean = sum / v.size();

#if _DEBUG
   str = to_string(index) + " : sum = " + to_string(sum) + " mean = " + to_string(mean) + " size of v = " + to_string(v.size());
   Print(str);
#endif

   BandsMain[index] = mean;

   vector<double> d(v.size());

   transform(v.begin(), v.end(), d.begin(), [mean](double x) { return x - mean; });
   double sq_sum = inner_product(d.begin(), d.end(), d.begin(), 0.0);
   double stdev = sqrt(sq_sum / (v.size()));

#if _DEBUG
   str = to_string(index) + " : sq_sum = " + to_string(sq_sum) + " stdev = " + to_string(stdev);
   Print(str);
#endif

   BandsUpper[index] = mean + (Deviation * stdev);
   BandsLower[index] = mean - (Deviation * stdev);
   StdDev[index] = Deviation * stdev;

   d.erase(d.begin(), d.end());
   v.erase(v.begin(), v.end());
}


Enjoy!


Return to “Indicators”

Who is online

Users browsing this forum: No registered users and 31 guests