How to draw a Filling like a Rectangle, in MQL5? - lines

can anybody suggest a way how to achieve this kind of drawing, as the official mql5 documentation does not point out this.
I have done the sample provided herebut it only outputs this result,which is not what I wanted.
anybody has any suggestion?

The simpler part: ... better forget Custom Indicators ( all share single-thread / block )
For a faster and safer GUI, with a full control over painting these orthogonal shapes, the New-MQL4/MQL5 languages can use something like this:
// --------------------------------------------------------------------
#define GUI_aFontSIZE 10
#define GUI_aFontNAME "Courier New"
#define GUI_aTradeCOLOR C'80,0,80'
#define GUI_aTPed_COLOR clrDarkGreen
#define GUI_aSLed_COLOR clrDarkRed
#define GUI_isSELECTABLE True
long GUI_aMainWINDOW = CharID();
int GUI_anObjNUMBER = 0;
string anInterimObjNAME = StringFormat( "GUI.DEMO_RectangularOBJECT_[%d]", GUI_anObjNUMBER );
if ( ObjectFind( anInterimObjNAME ) == GUI_aMainWINDOW )
ObjectDelete( anInterimObjNAME ); //--- prevent collisions
ObjectCreate( GUI_aMainWINDOW, anInterimObjNAME, OBJ_RECTANGLE, 0, aTimeOfENTRY, anEntryPRICE,
aTimeOfEXIT, DBL_MIN
);
ObjectSetInteger( GUI_aMainWINDOW, anInterimObjNAME, OBJPROP_COLOR, GUI_aSLed_COLOR ); //--- set color
ObjectSetInteger( GUI_aMainWINDOW, anInterimObjNAME, OBJPROP_BACK, True ); //--- display in the foreground (false) or background (true) ~ FILL-IT ~
ObjectSetInteger( GUI_aMainWINDOW, anInterimObjNAME, OBJPROP_SELECTABLE, GUI_isSELECTABLE ); //---------------------------------------- MAY AVOID GUI interactions
ObjectSetInteger( GUI_aMainWINDOW, anInterimObjNAME, OBJPROP_SELECTED, False ); //--- set GUI-object as (non)-pre-SELECT-ed
ObjectSetInteger( GUI_aMainWINDOW, anInterimObjNAME, OBJPROP_HIDDEN, False ); //--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger( GUI_aMainWINDOW, anInterimObjNAME, OBJPROP_ZORDER, 1 ); //--- set the "layered" priority for receiving a mouse-click-event in the chart
// --------------------------------------------------------------------
If in doubts, use the GUI objects dialogue-panels to experiment manually and derive the missing syntax explanation(s) in the language documentation.
May use a more complex & a way more risky approach:
If the story is to become based on a Custom Indicator, the toys get a bit more complex.
There is a hardcoded-engine, that processes data in a so called IndicatorBuffer.
In case, a particular data element there happens to equal to EMPTY_VALUE a special handling is provided for those particular bars.
Such EMPTY_VALUE constant signals to the processing-engine the values of indicators that are not shown in the chart, as did surprise you.
For example, for a built-in indicator Standard Deviation with a period of 20, the line for the first 19 bars in the history are not shown in the chart at all, using this feature trick. The same might be used anywhere further, all the way to the current bar[0], even dynamically, so as to emulate "vibrations" :o) ( do not risk this in production ... ).
This can also create "dropped" parts of the painted areas in aPriceDOMAIN displayed Custom Indicators.
For painting area "between" two generic Custom Indicator lines ( between "oscilating" curves ), one has to employ a few more tricks, using:
//--- plot dual-line-filled----------------------------------------------
#property indicator_label "DEMO-Custom-2-Line-Filled-Indicator"
#property indicator_type DRAW_FILLING // THE MAGIC FILL-STYLING
#property indicator_color clrAqua,clrSalmon // THE MAGIC FILL-STYLING
#property indicator_width 2
//--- Custom Indicator buffers -----------------------------------------
double aCustomIndicatorLineDATA_buffer1[];
double aCustomIndicatorLineDATA_buffer2[];
//--- Next, fill DATA as usually and the GUI shows the magic FILL-STYLING
Anyway:
Enjoy the Wild Worlds of MQL4/MQL5
Interested? May also like reading other MQL4 and low-latency trading posts

Related

A shortcut to get the point of previous frame plus its width?

Many times when i am programing a UI , i have to put some view after the previous view, so to get the previous value i am calculating its x/y position ,add to this its width/height, and get the desired frame to the next view ,
newX=previous.frame.origin.x+previous.frame.size.width;
newy=previous.frame.origin.y+previous.frame.size.height;
Is there a short way to get that value of a view ,in one word ?
When you have to do that many times , it becomes a real headache every time again .
You can use C functions declared in CoreGraphic.h:
newX = CGRectGetMaxX(previous.frame);
newy = CGRectGetMaxY(previous.frame);
You can define a macro
#define NextX(frame) (frame.origin.x+frame.size.width)
#define NextY(frame) (frame.origin.y+frame.size.height)
and then you can use it like
newX=NextX(previous.frame);
newY=NextY(previous.frame);

OpenCV - Variable value range of trackbar

I have a set of images and want to make a cross matching between all and display the results using trackbars using OpenCV 2.4.6 (ROS Hydro package). The matching part is done using a vector of vectors of vectors of cv::DMatch-objects:
image[0] --- image[3] -------- image[8] ------ ...
| | |
| cv::DMatch-vect cv::DMatch-vect
|
image[1] --- ...
|
image[2] --- ...
|
...
|
image[N] --- ...
Because we omit matching an image with itself (no point in doing that) and because a query image might not be matched with all the rest each set of matched train images for a query image might have a different size from the rest. Note that the way it's implemented right I actually match a pair of images twice, which of course is not optimal (especially since I used a BruteForce matcher with cross-check turned on, which basically means that I match a pair of images 4 times!) but for now that's it. In order to avoid on-the-fly drawing of matched pairs of images I have populated a vector of vectors of cv::Mat-objects. Each cv::Mat represents the current query image and some matched train image (I populate it using cv::drawMatches()):
image[0] --- cv::Mat[0,3] ---- cv::Mat[0,8] ---- ...
|
image[1] --- ...
|
image[2] --- ...
|
...
|
image[N] --- ...
Note: In the example above cv::Mat[0,3] stands for cv::Mat that stores the product of cv::drawMatches() using image[0] and image[3].
Here are the GUI settings:
Main window: here I display the current query image. Using a trackbar - let's call it TRACK_QUERY - I iterate through each image in my set.
Secondary window: here I display the matched pair (query,train), where the combination between the position of TRACK_QUERY's slider and the position of the slider of another trackbar in this window - let's call it TRACK_TRAIN - allows me to iterate through all the cv::Mat-match-images for the current query image.
The issue here comes from the fact that each query can have a variable number of matched train images. My TRACK_TRAIN should be able to adjust to the number of matched train images, that is the number of elements in each cv::Mat-vector for the current query image. Sadly so far I was unable to find a way to do that. The cv::createTrackbar() requires a count-parameter, which from what I see sets the limit of the trackbar's slider and cannot be altered later on. Do correct me if I'm wrong since this is exactly what's bothering me. A possible solution (less elegant and involving various checks to avoid out-of-range erros) is to take the size of the largest set of matched train images and use it as the limit for my TRACK_TRAIN. I would like to avoid doing that if possible. Another possible solution involves creating a trackbar per query image with the appropriate value range and swap each in my secondary windows according to the selected query image. For now this seems to be the more easy way to go but poses a big overhead of trackbars not to mention that fact that I haven't heard of OpenCV allowing you to hide GUI controls. Here are two example that might clarify things a little bit more:
Example 1:
In main window I select image 2 using TRACK_QUERY. For this image I have managed to match 5 other images from my set. Let's say those are image 4, 10, 17, 18 and 20. The secondary window updates automatically and shows me the match between image 2 and image 4 (first in the subset of matched train images). TRACK_TRAIN has to go from 0 to 4. Moving the slider in both directions allows me to go through image 4, 10, 17, 18 and 20 updating each time the secondary window.
Example 2:
In main window I select image 7 using TRACK_QUERY. For this image I have managed to match 3 other images from my set. Let's say those are image 0, 1, 11 and 19. The secondary window updates automatically and shows me the match between image 2 and image 0 (first in the subset of matched train images). TRACK_TRAIN has to go from 0 to 2. Moving the slider in both directions allows me to go through image 0, 1, 1 and 19 updating each time the secondary window.
If you have any questions feel free to ask and I'll to answer them as well as I can. Thanks in advance!
PS: Sadly the way the ROS package is it has the bare minimum of what OpenCV can offer. No Qt integration, no OpenMP, no OpenGL etc.
After doing some more research I'm pretty sure that this is currently not possible. That's why I implemented the first proposition that I gave in my question - use the match-vector with the most number of matches in it to determine a maximum size for the trackbar and then use some checking to avoid out-of-range exceptions. Below there is a more or less detailed description how it all works. Since the matching procedure in my code involves some additional checks that does not concern the problem at hand, I'll skip it here. Note that in a given set of images we want to match I refer to an image as object-image when that image (example: card) is currently matched to a scene-image (example: a set of cards) - top level of the matches-vector (see below) and equal to the index in processedImages (see below). I find the train/query notation in OpenCV somewhat confusing. This scene/object notation is taken from http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html. You can change or swap the notation to your liking but make sure you change it everywhere accordingly otherwise you might end up with a some weird results.
// stores all the images that we want to cross-match
std::vector<cv::Mat> processedImages;
// stores keypoints for each image in processedImages
std::vector<std::vector<cv::Keypoint> > keypoints;
// stores descriptors for each image in processedImages
std::vector<cv::Mat> descriptors;
// fill processedImages here (read images from files, convert to grayscale, undistort, resize etc.), extract keypoints, compute descriptors
// ...
// I use brute force matching since I also used ORB, which has binary descriptors and HAMMING_NORM is the way to go
cv::BFmatcher matcher;
// matches contains the match-vectors for each image matched to all other images in our set
// top level index matches.at(X) is equal to the image index in processedImages
// middle level index matches.at(X).at(Y) gives the match-vector for the Xth image and some other Yth from the set that is successfully matched to X
std::vector<std::vector<std::vector<cv::DMatch> > > matches;
// contains images that store visually all matched pairs
std::vector<std::vector<cv::Mat> > matchesDraw;
// fill all the vectors above with data here, don't forget about matchesDraw
// stores the highest count of matches for all pairs - I used simple exclusion by simply comparing the size() of the current std::vector<cv::DMatch> vector with the previous value of this variable
long int sceneWithMaxMatches = 0;
// ...
// after all is ready do some additional checking here in order to make sure the data is usable in our GUI. A trackbar for example requires AT LEAST 2 for its range since a range (0;0) doesn't make any sense
if(sceneWithMaxMatches < 2)
return -1;
// in this window show the image gallery (scene-images); the user can scroll through all image using a trackbar
cv::namedWindow("Images", CV_GUI_EXPANDED | CV_WINDOW_AUTOSIZE);
// just a dummy to store the state of the trackbar
int imagesTrackbarState = 0;
// create the first trackbar that the user uses to scroll through the scene-images
// IMPORTANT: use processedImages.size() - 1 since indexing in vectors is the same as in arrays - it starts from 0 and not reducing it by 1 will throw an out-of-range exception
cv::createTrackbar("Images:", "Images", &imagesTrackbarState, processedImages.size() - 1, on_imagesTrackbarCallback, NULL);
// in this window we show the matched object-images relative to the selected image in the "Images" window
cv::namedWindow("Matches for current image", CV_WINDOW_AUTOSIZE);
// yet another dummy to store the state of the trackbar in this new window
int imageMatchesTrackbarState = 0;
// IMPORTANT: again since sceneWithMaxMatches stores the SIZE of a vector we need to reduce it by 1 in order to be able to use it for the indexing later on
cv::createTrackbar("Matches:", "Matches for current image", &imageMatchesTrackbarState, sceneWithMaxMatches - 1, on_imageMatchesTrackbarCallback, NULL);
while(true)
{
char key = cv::waitKey(20);
if(key == 27)
break;
// from here on the magic begins
// show the image gallery; use the position of the "Images:" trackbar to call the image at that position
cv::imshow("Images", processedImages.at(cv::getTrackbarPos("Images:", "Images")));
// store the index of the current scene-image by calling the position of the trackbar in the "Images:" window
int currentSceneIndex = cv::getTrackbarPos("Images:", "Images");
// we have to make sure that the match of the currently selected scene-image actually has something in it
if(matches.at(currentSceneIndex).size())
{
// store the index of the current object-image that we have matched to the current scene-image in the "Images:" window
int currentObjectIndex = cv::getTrackbarPos("Matches:", "Matches for current image");
cv::imshow(
"Matches for current image",
matchesDraw.at(currentSceneIndex).at(currentObjectIndex < matchesDraw.at(currentSceneIndex).size() ? // is the current object index within the range of the matches for the current object and current scene
currentObjectIndex : // yes, return the correct index
matchesDraw.at(currentSceneIndex).size() - 1)); // if outside the range show the last matched pair!
}
}
// do something else
// ...
The tricky part is the trackbar in the second window responsible for accessing the matched images to our currently selected image in the "Images" window. As I've explained above I set the trackbar "Matches:" in the "Matches for current image" window to have a range from 0 to (sceneWithMaxMatches-1). However not all images have the same amount of matches with the rest in the image set (applies tenfold if you have done some additional filtering to ensure reliable matches for example by exploiting the properties of the homography, ratio test, min/max distance check etc.). Because I was unable to find a way to dynamically adjust the trackbar's range I needed a validation of the index. Otherwise for some of the images and their matches the application will throw an out-of-range exception. This is due to the simple fact that for some matches we try to access a match-vector with an index greater than it's size minus 1 because cv::getTrackbarPos() goes all the way to (sceneWithMaxMatches - 1). If the trackbar's position goes out of range for the currently selected vector with matches, I simply set the matchDraw-image in "Matches for current image" to the very last in the vector. Here I exploit the fact that the indexing can't go below zero as well as the trackbar's position so there is not need to check this but only what comes after the initial position 0. If this is not your case make sure you check the lower bound too and not only the upper.
Hope this helps!

Box2d - Changing contact filter on the fly

Im using cocos2d (iOS) and box2d to create a game.
I have come to the point where I need to change the contact filter mid simulation and wondering how to go about this.
I need to use maskbits and categorybits, which is fine, im just unsure how to apply them to a b2body mid game.
I'm thinking I may need to retrieve the original b2fixture or b2fixturedef of the b2body on initialization, alter the values accordingly then call a method to refresh - world.Refilter()?
Does this sound somewhat accurate?
Any advice is surely appreciated
Oliver.
b2Filter filter;
for ( b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext() ) {
f->GetFilterData( &filter );
filter.categoryBits = ...;
filter.maskBits = ...;
filter.groupIndex = ...;
f->SetFilterData( &filter );
}
Obviously this would change the filter settings for all fixtures on a body - if you want to be more selective you will have to be able to tell which fixture is which somehow. Eg. if you know it's the only circle fixture you could just look at the type of the fixture to decide, otherwise you would have to make use of the fixture's user data I guess.
You can iterate over all bodies in the b2World. On each body you can iterate over it's fixture and change it's filter. To identify your bodies you can use userData.
The answer from iforce2d might be obsolete. I got the following code working properly with box2d v2.2.1, cocos2D v2.0.0 using Xcode v4.5.2 (here I assume I have a pointer to a b2Body named 'body' with only one fixture, i.e., I don't iterate over all fixtures on the body):
b2Fixture *fix = body->GetFixtureList();
b2Filter filter = fix->GetFilterData();
filter.groupIndex = -1*kPlayerGroupIndex;
fix->SetFilterData(filter);
In the above code I prevent 'body' from colliding with my player body which also has the same groupIndex value, i.e., -1*kPlayerGroupIndex, where kPlayerGroupIndex is a positive integer constant. Any bodies with this negative groupIndex never collide with one another. You could also update the categoryBits or maskBits accordingly to prevent collisions.
GetFilterData(&filter) and SetFilterData(&filter) returned errors for me given the version numbers I quoted above.

DLL on Metatrader 4 doesn't update with incoming ticks

I have written a simple DLL as part of a custom indicator for Metatrader 4, which is called thus:
int start( ) {
double Rates[][6];
int MaximumRecords = ArrayCopyRates( Rates, Symbol(), 0 );
for( int zz = MaximumRecords; zz >= 0; zz-- ) {
OutPut[zz] = EMPTY;
}
GetSMAArray( Rates, MaximumRecords, Periods, OutPut );
return(0);
}
This works fine in that it plots as expected on the chart, but unfortunately it does not update with new, incoming ticks - it just plots on its initial call. What further code can I add to make the DLL update with incoming ticks? Almost all my searches have come up with variations on the use of
ExtCountedBars = IndicatorCounted();
to force a while loop to calculate, but these all apply to calculations contained in the .mq4 file itself. I want to force the DLL to recalculate. Secondly, I would like this recalculation to occur only on the completion of a bar and not on the arrival of all and every tick.
For the on new bar only thing, I technique is to keep last bar's (Bars[0]) date time information in a variable, and if it has changed, this means a new bar has come.
datetime lastBarDateTime;
int start(){
if(Time[0]==lastBarDateTime)
return(0);
lastBarDateTime = Time[0];
// codes to run on a new bar ...
}
For DLL part, I actually couldn't have understood where you are using DLL in that code.

cocos2d, CC_HONOR_PARENT_TRANSFORM_SCALE, how do i use this enum property?

I want to add a sprite2 to sprite1, scale the width of of sprite 1 without scaling sprite2.
I found the code below part of the Cocos2d api; CCSprite.h line 54, but I don't know how to use it nor what the "1<<2" means.
Basically, I'm doing the following but it's not working:
[self addChild: sprite1];
[sprite1 addChild: sprite2]
sprite1.scaleX = 2;
sprite2.CC_HONOR_PARENT_TRANSFORM_SCALE = false;???
Yeah not sure how to use the enum.
thank you
typedef enum {
//! Translate with it's parent
CC_HONOR_PARENT_TRANSFORM_TRANSLATE = 1 << 0,
//! Rotate with it's parent
CC_HONOR_PARENT_TRANSFORM_ROTATE = 1 << 1,
//! Scale with it's parent
CC_HONOR_PARENT_TRANSFORM_SCALE = 1 << 2,
//! All possible transformation enabled. Default value.
CC_HONOR_PARENT_TRANSFORM_ALL = CC_HONOR_PARENT_TRANSFORM_TRANSLATE | CC_HONOR_PARENT_TRANSFORM_ROTATE | CC_HONOR_PARENT_TRANSFORM_SCALE,
} ccHonorParentTransform;
<< - is a bit operation of a shift (my native language is russian and i've translated as is - not sure it's correct). But it is not required for you to understand how it work in this situation because in this case it's just a method to fill the enum values.
From cocos2d documentation
- (ccHonorParentTransform) honorParentTransform [read, write, assign]
whether or not to transform according to its parent transfomrations. Useful for health bars. eg: Don't rotate the health bar, even if the parent rotates. IMPORTANT: Only valid if it is rendered using an CCSpriteBatchNode.
Are you using batch rendering ?
EDIT:
This line is very strange (doesn't it give a warning?)
sprite2.CC_HONOR_PARENT_TRANSFORM_SCALE = false
You should write
sprite2.honorParentTransform &= ~CC_HONOR_PARENT_TRANSFORM_SCALE;
PS: The enum is created using bit operations because it's give you the ability to misc the configuration. For example you can write
sprite2.honorParentTransform &= ~(CC_HONOR_PARENT_TRANSFORM_SCALE | CC_HONOR_PARENT_TRANSFORM_ROTATE);
It will enable both translate and rotate
So the honorParentTransform is a bitmask, that allows you to configure it's configuration - not only use some predefined values but also use there combinations.
Here you can write more about bitwise operations
http://www.cprogramming.com/tutorial/bitwise_operators.html
In our case is happening something like this:
You have a current mask for example 01101111 (it is 32 bit really)
and CC_HONOR_PARENT_TRANSFORM_SCALE is something like this 00001000 - it have only one nonzero bit. ~ - is inversion: so it transform 00010000 to 11101111 and then you make the bitwise addition with you current mask - so all the bits will be preserved except the forth one!