Can't calculate the right Volume RSI in MQL4 with a functioning Pine-Script Example - mql4

I want to "translate" a Pine-Script to MQL4 but I get the wrong output in MQL4 compared to the Pine-Script in Trading-view.
I wrote the Indicator in Pine-Script since it seems fairly easy to do so.
After I got the result that I was looking for I shortened the Pine-Script.
Here the working Pine-Script:
// Pinescript - whole Code to recreate the Indicator
study( "Volume RSI", shorttitle = "VoRSI" )
periode = input( 3, title = "Periode", minval = 1 )
VoRSI = rsi( volume, periode )
plot( VoRSI, color = #000000, linewidth = 2 )
Now I want to translate that code to MQL4 but I keep getting different outputs.
Here is the MQL4 code I wrote so far:
// MQL4 Code
input int InpRSIPeriod = 3; // RSI Period
double sumn = 0.0;
double sump = 0.0;
double VoRSI = 0.0;
int i = 0;
void OnTick() {
for ( i; i < InpRSIPeriod; i++ ) {
// Check if the Volume is buy or sell
double close = iClose( Symbol(), 0, i );
double old_close = iClose( Symbol(), 0, i + 1 );
if ( close - old_close < 0 )
{
// If the Volume is positive, add it up to the positive sum "sump"
sump = sump + iVolume( Symbol(), 0, i + 1 );
}
else
{
// If the Volume is negative, add it up to the negative sum "sumn"
sumn = sumn + iVolume( Symbol(), 0, i + 1 );
}
}
// Get the MA of the sump and sumn for the Input Period
double Volume_p = sump / InpRSIPeriod;
double Volume_n = sumn / InpRSIPeriod;
// Calculate the RSI for the Volume
VoRSI = 100 - 100 / ( 1 + Volume_p / Volume_n );
// Print Volume RSI for comparison with Tradingview
Print( VoRSI );
// Reset the Variables for the next "OnTick" Event
i = 0;
sumn = 0;
sump = 0;
}
I already checked if the Period, Symbol and timeframe are the same and also have a Screenshoot of the different outputs.
I already tried to follow the function-explanations in the pine-script for the rsi, max, rma and sma function but I cant get any results that seem to be halfway running.
I expect to translate the Pine-Script into MQL4.
I do not want to draw the whole Volume RSI as a Indicator in the Chart.
I just want to calculate the value of the Volume RSI of the last whole periode (when new candel opens) to check if it reaches higher than 80.
After that I want to check when it comes back below 80 again and use that as a threshold wether a trade should be opened or not.
I want a simple function that gets the Period as an input and takes the current pair and Timeframe to return the desired value between 0 and 100.
Up to now my translation persists to provide the wrong output value.
What am I missing in the Calculation? Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?

Q : Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?
Your main miss of the target is in putting the code into a wrong type of MQL4-code. MetaTrader Terminal can place an indicator via a Custom Indicator-type of MQL4-code.
There you have to declare so called IndicatorBuffer(s), that contain pre-computed values of the said indicator and these buffers are separately mapped onto indicator-lines ( depending on the type of the GUI-presentation style - lines, area-between-lines, etc ).
In case you insist on having a Custom-Indicator-less indicator, which is pretty legal and needed in some use-cases, than you need to implement you own "mechanisation" of drawing lines into a separate sub-window of the GUI in the Expert-Advisor-code, where you will manage all the settings and plotting "manually" as you wish, segment by segment ( we use this for many reasons during prototyping, so as to avoid all the Custom-Indicator dependencies and calling-interface gritty-nitties during the complex trading exosystem integration - so pretty well sure about doability and performance benefits & costs of going this way ).
The decision is yours, MQL4 can do it either way.
Q : What am I missing in the Calculation?
BONUS PART : A hidden gem for improving The Performance ...
In either way of going via Custom-Indicator-type-of-MQL4-code or an Expert-Advisor-type-of-MQL4-code a decision it is possible to avoid a per-QUOTE-arrival re-calculation of the whole "depth" of the RSI. There is a frozen-part and a one, hot-end of the indicator line and performance-wise it is more than wise to keep static records of "old" and frozen data and just update the "live"-hot-end of the indicator-line. That saves a lot of the response-latency your GUI consumes from any real-time response-loop...

Related

Is there a way to have google sheets read imperial height as a number?

I'm making a sheet with details about a bunch of fictional characters, and one column I want to have is their height. I would also really like to use Conditional Formatting with a Color Scale to color-code the tallest and shortest characters, and everything in between.
Unfortunately, I live in the US, and am used to height expressed in feet and inches (e.g. 5'10''), which Google Sheets of course does not recognize as a number. Is there any way to remedy this, besides writing everything in terms of just inches (e.g. 60), such that I could apply conditional formatting directly to the column?
I've tried different formats (e.g. 5'10), and I considered having a hidden column with just the inch value and have conditional formatting work off of that row (doesn't work with Color Scale as far as I can tell, since you can't input a custom formula). One thought I had is somehow formatting things as an improper fraction with a denominator of 12, but hiding the denominator? But I have no idea how that would work. I've Googled as best I can, but I haven't found anything (everything's just about changing row height, which makes sense in hindsight).
I understand that you have two goals in mind. First of all, you should decide which unit length to use for managing heights. I have chosen inches, but you could work with feet if you need. This will simplify the scenario and will allow you to work easily with the data, but you could always create a function that translates inches to the foot/inches combo in order to show the data to a third party. This is the example table that I will use:
And this is my code, I will explain it at the bottom:
function main() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
data = sortTable(data);
sheet.getDataRange().setValues(data);
for (var i = 1; i < data.length; i++) {
data[i][2] = gradient(data.length, i);
}
for (var i = 1; i < data.length; i++) {
sheet.getRange(i, 2).setBackground("#" + data[i][2][0] + data[i][2][1] +
data[i][2][2]);
}
}
function sortTable(data) {
data.sort(function(a, b) {
return b[1] - a[1];
})
return data;
}
function gradient(arraySize, position) {
var relativePosition = position / arraySize;
var topColor = [parseInt("00", 16), parseInt("7A", 16), parseInt("33",
16)]; // Green
var bottomColor = [parseInt("FF", 16), parseInt("FF", 16), parseInt("FF",
16)]; // White
var positionColor = [0, 0, 0];
for (var i = 0; i < 3; i++) {
positionColor[i] = Math.floor(topColor[i] * (1 - relativePosition) +
bottomColor[i] * relativePosition).toString(16);
}
return positionColor;
}
First of all you have to read the data with a combination of getValues()/setValues(), and once you do that you can sort the table based on height so you can create the gradient later. Please notice how I separated the sorting function for better clarity.
After that you need the gradient color for setBackground(). To do so I developed a simple linear gradient function that calculates the RGB code from the top to the bottom. In my example the gradient fades from green to white, but you can change it. I also separated the gradient script into its own function. At this point you already have the sorted table and its gradient colors, so you only have to use setValues() and you are done. Feel free to leave any comment if you have doubts about this approach. This would be the final result:
UPDATE
Based in your comments I get that you need an imperial height format. For that case, you could use =INT(B2)&"' "&TRIM(TEXT(ROUND(MOD(B2,1)*12*16,0)/16,"# ??/??")&"""") (assuming that B2 contains the height). This approach will use Sheets Formulas to calculate the remainder part of the height, and its expression as an irreducible fraction. This is the final result:

Google Lighthouse Speed Index 100% visually completed frame definition

I'm looking for a way to optimize our website's Speed Index metric on Lighthouse
I found this helpful article describe Speed Index metric very well, and help me understand how Speed Index is calculated.
https://calendar.perfplanet.com/2016/speed-index-tips-and-tricks/
But there is a key concept not being described clear on the article, and I search for a lot of other Speed Index related blogs still can't found the answer.
What is the 100% visual completeness frame?
We all know the First Frame is 0% VC because it's blank, but the VC keep increasing during the page load process, so what frame will be consider as 100% visual completeness?
The definition of 100% VC frame is important because it's the baseline for calculate all other frame's visual completeness.
If I have a page that simply print from 1 to 100 with interval 100ms and just enough to fill in the viewport, will the 100% VC frame be the frame that number 100 is printed?
Lighthouse
According to Google's description of the Lighthouse "Speed Index" audit:
Lighthouse uses a node module called Speedline to generate the Speed Index score.
sends Speedline
Speedline's Github readme says
The Speed Index, introduced by WebpageTest.org, aims to solve this issue. It measures how fast the page content is visually displayed. The current implementation is based on the Visual Progress from Video Capture calculation method described on the Speed Index page. The visual progress is calculated by comparing the distance between the histogram of the current frame and the final frame.
(Italics mine.)
a timeline of paints
The Speed Index page goes into painful detail about how visual progress is calculated. Here's a snippet:
In the case of Webkit-based browsers, we collect the timeline data which includes paint rects as well as other useful events.
I believe "timeline data" refers to a JSON object retrieved via the Performance Timeline API.
It seems Lighthouse passes the JSON timeline to Speedline, which then extracts an array of "frames," describing the page load's paint events:
/**
* #param {string|Array<TraceEvent>|{traceEvents: Array<TraceEvent>}} timeline
* #param {Options} opts
*/
function extractFramesFromTimeline(timeline, opts) {
which calculates histograms
Speedline converts the image data from each paint event to an image histogram, interestingly excluding pixels that are "close enough" to pass as white:
/**
* #param {number} i
* #param {number} j
* #param {ImageData} img
*/
function isWhitePixel(i, j, img) {
return getPixel(i, j, 0, img.width, img.data) >= 249 &&
getPixel(i, j, 1, img.width, img.data) >= 249 &&
getPixel(i, j, 2, img.width, img.data) >= 249;
}
A lot of math goes into calculating and comparing histograms. The project maintainer is the right person to ask about that. But this is where the eventual determination of the "visually complete" happens:
// find visually complete
for (let i = 0; i < frames.length && !visuallyCompleteTs; i++) {
if (frames[i][progressToUse]() >= 100) {
visuallyCompleteTs = frames[i].getTimeStamp();
}
}
and infers "progress",
The "progress" of a given frame seems to be calculated by this function:
/**
* #param {Frame} current
* #param {Frame} initial
* #param {Frame} target
*/
function calculateFrameProgress(current, initial, target) {
let total = 0;
let match = 0;
const currentHist = current.getHistogram();
const initialHist = initial.getHistogram();
const targetHist = target.getHistogram();
for (let channel = 0; channel < 3; channel++) {
for (let pixelVal = 0; pixelVal < 256; pixelVal++) {
const currentCount = currentHist[channel][pixelVal];
const initialCount = initialHist[channel][pixelVal];
const targetCount = targetHist[channel][pixelVal];
const currentDiff = Math.abs(currentCount - initialCount);
const targetDiff = Math.abs(targetCount - initialCount);
match += Math.min(currentDiff, targetDiff);
total += targetDiff;
}
}
let progress;
if (match === 0 && total === 0) { // All images are the same
progress = 100;
} else { // When images differs
progress = Math.floor(match / total * 100);
}
return progress;
}
and "visually complete" is the first frame with 100% progress.
Without fully auditing the code, my interpretation is that the "visually complete frame" is the first frame calculated to have the same total difference from the initial frame as the final frame (which is determined by which frames Lighthouse chooses to send to Speedline).
Or, in other words, it's complicated.
Visually complete is when the page in the viewport stops changing. I.e. the visuals are not changing.
It is calculated by taking screenshots throughout the load and comparing them to each other and to the final end state. So yes in your example when all numbers 1-100 are printed and the page stops changing you are “visually complete”.
So if a page loads the data in view quickly but renders “below the fold” content (e.g. off screen images) more slowly then you will get a quick visually complete, even if the page overall load time is still long.
Similarly if most of the on screen content is drawn early on but one small part is drawn later (perhaps a “click to chat” option) you will get mostly visually complete early on and so a good speed index, even if not as good as the above example.
On the other hand if you load fonts, or perhaps a large hero image, last and it redraws large parts of the page in view you will get a slow visual complete time and also a slow speed index score.
More details here: https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index
I just got the answer from Lighthouse repo contributor, pls check this link guys.
https://github.com/GoogleChrome/lighthouse/issues/8148

How to count how many bars back the moving average crossed last?

I am writing an MQL4 Custom Indicator that would tell how many bars ago a particular set of moving averages crossed.
To be specific, I want the output to show me that
"The 20 period MA( .. PRICE_OPEN ) is below MA( .. PRICE_CLOSE ) for the past 10 bars".
in a form of an int number.
double ma1 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_OPEN, 0 );
double ma2 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_CLOSE, 0 );
I want to find out that ma1 has been above or below ma2 for how many bars since the current bar.
TLDR;
MQL4 Custom Indicator design is a bit schizophrenic task with 2 parts
Once decided to design a Custom Indicator, one has to pay attention to both sides of the coin.
MQL4 code has a non-trivial signature for a caller-side( normally an
Expert Advisor or a Script type of MQL4 code )and
Custom Indicator, on it's own, operates in a special mode, where it calculates & store it's values into one or more arrays called IndexBuffer-s.
Phase I.: design Caller-side interface ( what all do we need to set / receive ? )
Phase II.: design Custom Indicator implementation side
This way, the given indicator shall
set just one parameter: a period ... 20
receive just one int a value of days { +:above | 0: xoss | -: under }
Phase I. : Design Caller-side interface
Given the above parametrisation and the MQL4 concept of Custom Indicator construction, the following universal template ( recommended to be routinely maintained as a commented section right in CustomIndicator-file ) reflects details needed for the Caller-side interface ( which one benefits from by just a copy-paste mechanics, while the implementation-integrity responsibility is born by the CustomIndicator maintainer ):
// CALL-er SIDE INTERFACE |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//
// #define sIndicatorPathNAME "#AliceInTheWonderlands_msMOD_0.00"
//
// //_____________________________________INPUT(s)
// // iMA_PERIOD:
// extern int iMA_PERIOD = 20;
//
// //_____________________________________OUTPUT(s):
// #define iOutputDoubleUpOrDnBUFFER 0
//
// //_____________________________________CALL-SIGNATURE:
//
// double iCustom( _Symbol, // string symbol, // symbol: Symbol name on the data of which the indicator will be calculated. NULL means the current symbol.
// PERIOD_W1, // int timeframe, // timeframe
// sIndicatorPathNAME, // string name, // path/name of the custom indicator compiled program: Custom indicator compiled program name, relative to the root indicators directory (MQL4/Indicators/). If the indicator is located in subdirectory, for example, in MQL4/Indicators/Examples, its name must be specified as "Examples\\indicator_name" (double backslash "\\"must be specified as separator instead of a single one).
// iMA_PERIOD, // ...[1] ..., // custom indicator [1]-st input parameter
// <<N/A>>, // ...[2+] // custom indicator further input parameters (if necessary)
// iOutputDoubleUpOrDnBUFFER, // int mode, // line index: Line index. Can be from 0 to 7 and must correspond with the index, specified in call of the SetIndexBuffer() function.
// i // int bar_shift // shift
// );
// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Typical Expert Advisor call looks like this:
int anIndicatorVALUE = iCustom( _Symbol,
PERIOD_W1,
sIndicatorPathNAME,
iMA_PERIOD,
iOutputDoubleUpOrDnBUFFER,
aCurrentBarPTR
);
if ( 0 > anIndicatorVALUE ) // on "line" under for <anIndicatorVALUE> [PERIOD]-s
{ ...
}
Phase II. : Design Custom Indicator implementation side
Preset an overall capacity
#property indicator_buffers 1 // compile time directive
Allocate memory for IndexBuffer(s) needed
IndicatorBuffers( 1 ); // upper limit of 512 is "far" enough
Declare IndexBuffer
double UpOrDnBUFFER[]; // mandatory to be a double
Associate IndexBuffer with an index
SetIndexBuffer( 0, UpOrDnBUFFER ); // index 0: UpOrDnBUFFER[]
ArraySetAsSeries( UpOrDnBUFFER, True ); // reverse AFTER association
The core logic of any Custom Indicator is inside an OnCalculate() function, where you
- implement desired calculusand- store resulting values into respective cells of the UpOrDnBUFFER[];
Writing a fully fledged code upon request is not the key objective of StackOverflow, but let me sketch a few notes on this, as Custom Indicator implementation side requires a bit practice:
because Custom Indicator OnCalculate() operates "progressively", so do design your calculation strategy & keep in mind the state-less-ness between "blocks" of forward-progressive blocks of calculations.
as given, crosses are tri-state system, so watch issues on cases, where decisions are made on a "live" bar, where the state { above | cross | under } may change many times during the bar-evolution.

MQL4 iCustom returns always the same (wrong) value (0x7FFFFFFF)

I wrote a custom indicator Speed.mq4 as follows:
double SpeedBuffer[]; // a Custom Indicator BUFFER
int OnInit() {
SetIndexBuffer( 0, SpeedBuffer ); // an access INDEX 0->BUFFER
...
}
int OnCalculate( const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[]
) {
int start;
if ( prev_calculated == 0 ) start = 1;
else start = prev_calculated - 1;
for ( int i = start; i < rates_total - 1 ; i++ ) { // CPU-WASTED BY AN INEFFICIENT BACK-STEPPING IN TIME
double curTypical = typical( high[i], low[i], close[i] );
double prevTypical = typical( high[i+1],low[i+1],close[i+1] ); // CPU-WASTED, NO NEED TO RECALC ...
double curSpeed = curTypical - prevTypical;
SpeedBuffer[i] = curSpeed;
}
//--- return value of prev_calculated for next call
return( rates_total );
}
The indicator works fine in the application and the chart is plotted correctly.
When I try retrieving the last value in the ExpertAdvisor I always receive the same value:
double speed = iCustom( NULL, 0, "Speed", 2, 0, 0 );
Print( "speed is: " + speed );
prints:
speed is: 2147483647
It's always the same number. I'm not sure where's the problem.
from the Print in the indicator I can see the values are calculated correctly. but when I use iCustom I receive only that value.
MQL4 Custom Indicator iCustom() mechanics
MQL4 and even the New-MQL4 ( sometime called an MQL4.5 ) use a rather complicated interfacing model to handle Expert Advisor call / Custom Indicator computations.
A first thing to realise is, that iCustom() is not a call to a function, but rather a method, that indirectly "asks" a by-a-filename referred Custom Indicator to retrieve one, specific, value from a "pre-calculated" DataSTORE.
While it may sound complicated, it is the very nature of a CPU-efficient calculation factory, that the Custom Indicators were designed for in the early days of MQL4 world.
iCustom() is thus just a syntax-sugar to initiate the retrieval method, that gets the relevant piece of pre-calculated value back into the hands of Expert Advisor.
Custom Indicators put all the pre-calculated values into BUFFER(s), co-aligned with the TimeSeries style of ordering the DataSTORE cells ( [0] == "Now, the current Bar", going forwards [1], [2], [3], ... deeper and deeper back into the history )
The iCustom() passes the shift value, as a number of bars -- i.e. how deep into the history the retrieving method has to go, so as to pick the requested value from the respective BUFFER, and also the BUFFER identification INDEX ( 0 in our case above, as there is just a single BUFFER, with INDEX == 0 ). This is used for the sake of the EA being fully agnostic of the Custom Indicator internal variable names et al.
Just ask which BufferINDEX for which BarNUMBER one wants the value to be read from.
The Buffer is the one, who is to be blamed for the (wrong) value
The first line of the code says:
double SpeedBuffer[]; // a Custom Indicator BUFFER
If not handled otherwise in OnInit(){} all cells in the SpeedBuffer will have
EMPTY_VALUE
Empty value in an indicator buffer has by default this value == 2147483647 (0x7FFFFFFF) as has been objected above.
Q.E.D.
One may state in OnInit(){ ArrayInitialize( SpeedBuffer, 0.123456 ); } to have any other value for a cell-initialisation ( that for a TimeSeries-alligned BUFFERs happens upon each new-Bar event ( all cells get reshuffled by one backwards & cell[0] becomes "empty", pre-loaded with a default value discussed here ) ).
One may also add a step in an indicator OnCalculate(){ ... SpeedBuffer[0] = -9.87654; ...} so as to avoid leaving the cell[0] in a context-inconsistent state, not in a "just"-initialised state / value.
Caller-side interface ( how to reduce a risk on a weak-integration interface )
Nevertheless, the responsibility of the value retrieval is on the Expert Advisor side, as it fills the parameters of the iCustom() interface-proxy.
One may use preventive steps as shown in >>> https://stackoverflow.com/a/26389823/3666197
to minimise a risk of improper parameters ordering / values once calling an external Custom Indicator(s) to retrieve a set of values.
This simple method may save you literally tens of man*days of testing/debugging once a rich-extern-parametrised Custom Indicator with several indicator buffers has fallen into suspects due to serving "wrong" numbers ( just due to iCustom() call parameters being "invisibly" out of proper order/context )
Another thing to keep in mind when a custom indicator shows different values on the chart then are reported to the ExpertAdvisor, is that the execution flow through OnCalculate() needs to be different for an ExpertAdvisor than it is for a chart; specifically, the chart initially kicks off a call to OnCalculate() with prev_calculated = 0, whereas an EA (whether run with Strategy Tester or live) will always have prev_calculated = rates_total-1, so that the number of bars to compute the indicator value for is rates_total - prev_calcualted = 1 (ie. just the current bar).
You do account for this in your code, by setting start, but in general for a complicated indicator (that often involves referencing more than just the previous bar) one needs to be mindful of this difference and never assume that if the indicator looks good on the chart that means it's actually working. It needs to be tested separately with an EA.
I reviewed my code and finally figured that:
double speed=iCustom(NULL,0,"Speed",2,0,0);
was using the last value, which was not yet calculated by the custom indicator,
changing it to:
double speed=iCustom(NULL,0,"Speed",2,0,1);
did the trick.

Scaling of Gaussian Equation

I'm using Gaussian equation for a particular photo effect in an iOS application.
I use:
double sigmaX = ...; //some value here
for(int i=0;i<height;i++)
{
double F = 0;
double step = -(pos)*width/20;
/*height,width,pos - all predefined, no problem there*/
for(int j=0;j<4*width;j+=4)
{
F = (double) ((1/1)*exp(-sigmaX*(pow((step++)/1, 2.0)))) ;
//do some operation here...
}
}
and the value of F is used to determine a particular intensity which is used up elsewhere.
So far so good.... F is the typical bell curve as expected.
But, the question is, I want to scale the standard deviation of this curve as per user input.
For example, in the following image, I'd like to shift the curve from the green to the red line (blue maybe an intermediate), hopefully in linear steps:
Now, given the standard notation of:
and comparing it with the way I implemented it in my code, I got the idea to vary 1/sqrt(sigmaX) to alter the scale/SD. I tried incrementing 1/sqrt(sigmaX) in linear steps (to get linear increment) or by x^n to get power of n increment in SD, but none of that worked.
I am a bit stuck with the concept.
Can you please let me know how to scale the Standard Deviation by a predefined ratio, i.e I may want it 1.34 or 3.78 times the oirginal SD and it will scale up the the +3sigma to -3sigma span accordingly.
Your calculation here:
F = (double) ((1/1)*exp(-sigmaX*(pow((step++)/1, 2.0)))) ;
Is not reflecting the Gaussian formula you showed. It should be something like this:
double dSigma = 1.0;
static const double dRootTwoPi = sqrt(2.0 * M_PI);
F = (1.0 / (dSigma * dRootTwoPi)) * exp(-0.5 * pow(step++ / dSigma, 2.0));
Then you can vary dSigma from 1.0 to 3.0 (or whatever) to get the effect you want.
Thanks Roger Rowland, for the help... I finally got this to work:
Changed the gaussian function to:
sigmaX*=scaling;
F = (double) ((scaling / (sigmaX))*exp(-0.0005*(powf((step++/sigmaX), 2.0)))) ;
Indeed, what I had done before wasn't exactly Gaussian. This works fine and scales fine, based on the scaling parameter.
Thanks again.

Resources