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.