I am trying to calculate the lower 2SD and higher 2SD for a ratio of the price for two instruments, however, it is giving me 0 results. The expected results look like this. enter image description here
I tried to create an array by declaring the array in global scope and then adding values to it, however it is giving me zero as value, I also tried to add values manually to check if it is working but the function StdDev is also giving me same results. Any help to guide me where I am wrong would be deeply appreciated.
These are the codes tried by me, however not giving me any result.
d[z] = iClose(sym1,0,z)/iClose(sym2,0,z);
c = iStdDevOnArray(iClose(sym1,0,z),0,z,0,0,z);
The code I am deploying is as below.
#property indicator_separate_window
#property indicator_buffers 4
extern string sym1 = "AUDUSD";
extern string sym2 = "NZDUSD";
extern int barcount = 500;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
//Global Variables
int ArrayIndex;
double ArraySum;
double a = 0;
double b=0;
double c=0;
double lowersd=0;
double highersd=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE,EMPTY,2,clrYellow);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexStyle(1,DRAW_LINE,EMPTY,2,clrRed);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexStyle(2,DRAW_LINE,EMPTY,2,clrGreen);
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexStyle(3,DRAW_LINE,EMPTY,2,clrPink);
SetIndexBuffer(3,ExtMapBuffer4);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//----
for(int z=0;z<barcount;z++)
{
// To calculate the average of the ratio
a=iClose(sym1,0,z)+a;
// Alert(d[0]);
b=iClose(sym2,0,z)+b;
// Below are the dummy data to create the chart
lowersd = 1.04;
highersd = 1.115;
}
for(int i=0;i<barcount;i++)
{
ExtMapBuffer1[i] = iClose(sym1,0,i)/iClose(sym2,0,i);
ExtMapBuffer2[i] = (a/b);
ExtMapBuffer3[i] = lowersd; // these are dummy values i am trying to populate this dynamically using the non working code above.
ExtMapBuffer4[i] = highersd;
}
//----
return(0);
}
You can use this to first initialize the array
double arr[];
ArrayResize(arr, barcount);
arr[z] = iClose(sym1,0,z)/iClose(sym2,0,z);
c=iStdDevOnArray(arr,barcount,barcount,0,MODE_EMA,0);
Then you can put this value in ExtBuffer
ExtMapBuffer3[i] = (a/b)-(c*2);
ExtMapBuffer4[i] = (a/b)+(c*2);
Related
I took the code of VIDYA from the examples library of MQL5 and added a second moving average to it; basically, another VIDYA line.
The newly created code is compiling without errors or warnings but only one moving average (VIDYA) is being displayed on the chart instead of two. It seems I am missing something. Your help will be much appreciated!
#property copyright "2009-2020, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property description "Double Variable Index Dynamic Average"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
#property indicator_type1 DRAW_LINE
#property indicator_color1 Navy
#property indicator_width1 3
#property indicator_label1 "VIDYA 1"
#property indicator_type2 DRAW_LINE
#property indicator_color2 Navy
#property indicator_width2 3
#property indicator_label2 "VIDYA 2"
#property indicator_applied_price PRICE_MEDIAN
//--- input parameters
input int InpPeriodCMO = 9; // Period CMO
input int InpPeriodEMA = 12; // Period EMA
input int InpShift = 0; // Indicator's shift
//--- indicator buffer
double VIDYA_Buffer_1[];
double VIDYA_Buffer_2[];
double ExtF; // smooth factor
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0, VIDYA_Buffer_1, INDICATOR_DATA);
SetIndexBuffer(1, VIDYA_Buffer_2, INDICATOR_DATA);
//--- sets first bar from what index will be drawn
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpPeriodEMA+InpPeriodCMO-1);
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpPeriodEMA+InpPeriodCMO-1);
//--- sets indicator shift
PlotIndexSetInteger(0, PLOT_SHIFT, InpShift);
PlotIndexSetInteger(1, PLOT_SHIFT, InpShift);
//--- name for indicator label
string short_name = StringFormat("VIDYA(%d,%d)", InpPeriodCMO, InpPeriodEMA);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
PlotIndexSetString(0, PLOT_LABEL, short_name+"1");
PlotIndexSetString(1, PLOT_LABEL, short_name+"2");
//--- calculate smooth factor
ExtF = 2.0/(1.0+InpPeriodEMA);
}
//+------------------------------------------------------------------+
//| Variable Index Dynamic Average |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
if(rates_total < InpPeriodEMA+InpPeriodCMO-1)
return(0);
//---
int i,start;
if(prev_calculated < InpPeriodEMA+InpPeriodCMO-1)
{
start = InpPeriodEMA+InpPeriodCMO-1;
for(i = 0; i<start; i++)
{
VIDYA_Buffer_1[i] = price[i];
VIDYA_Buffer_2[i] = price[i];
}
}
else
start = prev_calculated-1;
//--- main cycle
for(i = start; i<rates_total && !IsStopped(); i++)
{
double mul_CMO = MathAbs(CalculateCMO(i,InpPeriodCMO,price));
//--- calculate VIDYA 1 & 2
VIDYA_Buffer_1[i] = price[i]*ExtF*mul_CMO+VIDYA_Buffer_1[i-1]*(1-ExtF*mul_CMO)*1;
VIDYA_Buffer_2[i] = price[i]*ExtF*mul_CMO+VIDYA_Buffer_2[i-1]*(1-ExtF*mul_CMO)*2;
}
//--- OnCalculate done. Return new prev_calculated.
return(rates_total);
}
//+------------------------------------------------------------------+
//| Chande Momentum Oscillator |
//+------------------------------------------------------------------+
double CalculateCMO(int pos,const int period,const double &price[])
{
double res = 0.0;
double sum_up = 0.0,sum_down = 0.0;
//---
if(pos >= period && pos<ArraySize(price))
{
for(int i = 0; i<period; i++)
{
double diff = price[pos-i]-price[pos-i-1];
if(diff>0.0)
sum_up += diff;
else
sum_down += (-diff);
}
if(sum_up+sum_down != 0.0)
res = (sum_up-sum_down)/(sum_up+sum_down);
}
//---
return(res);
}
Below is the method I'm using to place an order after three minutes if it doesn't go through. I've converted the larger part of it from mql4 to mql5. It's just the commented part that I'm not sure how I'll change to mql5 since in mql5 send orders return bool's and not int's. I would be glad if I could get help with fixing this remaining part.
void MakeOrders()
{
static datetime lastTime = 0;
datetime currTime = iTime(Symbol(),PERIOD_M3,0);
if (currTime>lastTime)
{
for (int i=ObjectsTotal(0, 0, -1)-1; i>=0; i--)
{
string name = ObjectName(0, i, 0, -1);
if (ObjectGetString(0, name, OBJPROP_NAME, 0)==OBJ_RECTANGLE && ObjectGetString(0,name,OBJPROP_TEXT)=="")
{
double entryPrice=ObjectGetDouble(0,name,OBJPROP_PRICE,1)-3*_Point;
double stopLoss=ObjectGetDouble(0,name,OBJPROP_PRICE,2);
double slDist=fabs(entryPrice-stopLoss);
double dTakeProfit=entryPrice-2*slDist;
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- parameters of request
request.action =TRADE_ACTION_DEAL; // type of trade operation
request.symbol =Symbol(); // symbol
request.volume =lotSize; // volume of 0.1 lot
request.type =ORDER_TYPE_BUY_LIMIT; // order type
request.price = entryPrice; // price for opening
//request.deviation=5; // allowed deviation from the price
request.magic =magicnumber; // MagicNumber of the order
request.tp = dTakeProfit;
request.sl = stopLoss;
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
/*
int ticketSell = OrderSend(Symbol(),OP_SELLLIMIT,lotSize, entryPrice,0,stopLoss,dTakeProfit,"SellOrder",magicnumber,0,Red);
if (ticketSell>0)
{
ObjectSetText(name,string(ticketSell));
i = ObjectsTotal()-1; // rather than continuing the 'for' loop, we must restart because arrows (ie new objects) were created.
}
*/
}
}
lastTime = currTime;
}
}
if(result.retcode==10009 || result.order>0)
ObjectSetText(name,string(result.order));
I'm trying to find a super fast way of getting the sign of each value in a vector. I was hoping to find a function in the accelerate framework to do this, but couldn't find one. Here's what it would do:
float *inputVector = .... // some audio vector
int length = ...// length of input vector.
float *outputVector = ....// result
for( int i = 0; i<length; i++ )
{
if( inputVector[i] >= 0 ) outputVector[i] = 1;
else outputVector[i] = -1;
}
Ok, I think I've found a way...
vvcopysignf() "Copies an array, setting the sign of each value based on a second array."
So, one method would be to make an array of 1s, then use this function to change the sign of the 1s based on an input array.
float *ones = ... // a vector filled with 1's
float *input = .... // an input vector
float *output = ... // an output vector
int bufferSize = ... // size of the vectors;
vvcopysignf(output, ones, input, &bufferSize);
//output now is an array of -1s and 1s based the sign of the input.
I want to count the total non-zero points number in an image using OpenCL.
Since it is an adding work, I used the atom_inc.
And the kernel code is shown here.
__kernel void points_count(__global unsigned char* image_data, __global int* total_number, __global int image_width)
{
size_t gidx = get_global_id(0);
size_t gidy = get_global_id(1);
if(0!=*(image_data+gidy*image_width+gidx))
{
atom_inc(total_number);
}
}
My question is, by using atom_inc it will be much redundant right?
Whenever we meet a non-zero point, we should wait for the atom_inc.
I have a idea like this, we can separate the whole row into hundreds groups, we find the number in different groups and add them at last.
If we can do something like this:
__kernel void points_count(__global unsigned char* image_data, __global int* total_number_array, __global int image_width)
{
size_t gidx = get_global_id(0);
size_t gidy = get_global_id(1);
if(0!=*(image_data+gidy*image_width+gidx))
{
int stepy=gidy%10;
atom_inc(total_number_array+stepy);
}
}
We will separate the whole problem into more groups.
In that case, we can add the numbers in the total_number_array one by one.
Theoretically speaking, it will have a great performance improvement right?
So, does anyone have some advice about the summing issue here?
Thanks!
Like mentioned in the comments this is a reduction problem.
The idea is to keep separate counts and then put them back together at the end.
Consider using local memory to store the values.
Declare a local buffer to be used by each work group.
Keep track of the number of occurrences in this buffer by using the local_id as the index.
Sum these values at the end of execution.
A very good introduction to the reduction problem using Opencl is shown here:
http://developer.amd.com/resources/documentation-articles/articles-whitepapers/opencl-optimization-case-study-simple-reductions/
The reduction kernel could look like this (taken from the link above):
__kernel
void reduce(
__global float* buffer,
__local float* scratch,
__const int length,
__global float* result) {
int global_index = get_global_id(0);
int local_index = get_local_id(0);
// Load data into local memory
if (global_index < length) {
scratch[local_index] = buffer[global_index];
} else {
// Infinity is the identity element for the min operation
scratch[local_index] = INFINITY;
}
barrier(CLK_LOCAL_MEM_FENCE);
for(int offset = get_local_size(0) / 2;
offset > 0;
offset >>= 1) {
if (local_index < offset) {
float other = scratch[local_index + offset];
float mine = scratch[local_index];
scratch[local_index] = (mine < other) ? mine : other;
}
barrier(CLK_LOCAL_MEM_FENCE);
}
if (local_index == 0) {
result[get_group_id(0)] = scratch[0];
}
}
For further explanation see the proposed link.
Im using classes to create a function. The function must find a selected colour in the image provided. So I made it so that the function takes a Vec3b value since it is an RGB value we are talking about.
class colorcompare
{
private:
int threshold;
Vec3b color;
void setcolor(Vec3b);
Mat process(Mat&);
void setthresh(const int);
int getdist(Vec3b);
};
void colorcompare::setcolor(Vec3b colr)
{
color = colr;
}
int _tmain(int argc, _TCHAR* argv[])
{
colorcompare cc1;
Mat image;
image = imread("c:\\car2.jpg", -1);
cc1.setcolor(19,69,139); //This is where im getting error
cc1.setthresh(100);
namedWindow("meh");
imshow("meh", cc1.process(image));
waitKey(0);
return 0;
}
Now the error I am getting is this: 'colorcompare::setcolor' : function does not take 3 arguments
I know that vec3b is a vector of 3 values, so in other words I can access the individual values of vec3b as color[0], color[1] and color[2].
And I know I can define it like such in the function above but it shouldnt the vec3b be able to take 3 values? Like I did in my code?
Classic mistake: the function expects a cv::Vec3b object, not 3 int variables.
If you want a single line solution, try this:
cc1.setcolor(cv::Vec3b(19,69,139));
You defined setColor to take a Vec3b as parameter, so you should give it a Vec3b:
cv::Vec3b color(19,69,139); // or cv::Vec3b color; color[0]=19, ...
cc1.setColor(color);