//+------------------------------------------------------------------+ //| my_Point_and_Figure.mq4 | //| Copyright © 2009, EarnForex.com | //| http://www.earnforex.com | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, EarnForex.com" #property link "http://www.earnforex.com" #property indicator_chart_window //Define directions #define NONE 0 #define UP 1 #define DOWN -1 extern color ColorUp = Red; //Color of the X extern color ColorDown = Green; //Color of the O extern int BoxSize = 6; //Box size in pips (classical pips) extern int Reversal = 3; //18Reversal size in pips (also classical) extern int Distance = 3; //4Vertical distance to draw Xs or Os; in classical pips //Converted parameters in classical pips double cBoxSize; double cReversal; double cDistance; double Last = 0; //Stores last price where a box was drawn double CurrentDirection = NONE; //Stores current direction (surprise!) double FirstBoxUp = 0; double FirstBoxDown = 0; int Number = 0; //Order number of the object int LastBars = 0; //Amount of bars //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { cBoxSize = BoxSize * Point; cReversal = Reversal * Point; cDistance = Distance * Point; //For non-classical pip size if ((Point == 0.001) || (Point == 0.00001)) { cBoxSize *= 10; cReversal *= 10; cDistance *= 10; } return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { for (int i = 0; i < Number; i++) { ObjectDelete("XO-" + i); } return(0); } //+------------------------------------------------------------------+ //| Capture every tick and draw X or O if necessary | //+------------------------------------------------------------------+ int start() { if ((LastBars < Bars) && (LastBars != 0)) { MoveAllRight(); if (Number > 1000) Print("Warning: Too Many X/O Bars!"); } LastBars = Bars; if (CurrentDirection == NONE) { //First X if ((Bid >= FirstBoxUp) && (FirstBoxUp != 0)) DrawX(); //First O if ((Ask <= FirstBoxDown) && (FirstBoxDown != 0)) DrawO(); if (FirstBoxUp == 0) FirstBoxUp = Bid + cBoxSize; if (FirstBoxDown == 0) FirstBoxDown = Ask - cBoxSize; return(0); } if (CurrentDirection == UP) { if (Bid >= (Last + cBoxSize)) { DrawX(); Print("X Drawn.");} if (Ask <= (Last - cReversal)) { DrawO(); Print("O Drawn on Reversal.");} return(0); } if (CurrentDirection == DOWN) { if (Ask <= (Last - cBoxSize)) { DrawO(); Print("O Drawn.");} if (Bid >= (Last + cReversal)) { DrawX(); Print("X Drawn on Reversal.");} return(0); } return(0); } void DrawX() { if (CurrentDirection == DOWN) MoveAllLeft(); //Reversal, need to form a new column ObjectCreate("XO-" + Number, OBJ_TEXT, 0, Time[0], Bid); if (CurrentDirection != NONE) //Not first X { //Get the previous object vertical position double pp = ObjectGet("XO-" + (Number - 1), OBJPROP_PRICE1); if (CurrentDirection == UP) ObjectSet("XO-" + Number, OBJPROP_PRICE1, pp + cDistance); else ObjectSet("XO-" + Number, OBJPROP_PRICE1, pp); } ObjectSetText("XO-" + Number, "x", 9, "Arial", ColorUp); Number++; if (Last != 0) { if (CurrentDirection == UP) Last = Last + cBoxSize; else Last = Last + cReversal; } else Last = Bid; CurrentDirection = UP; Print("X: ", Last); } void DrawO() { if (CurrentDirection == UP) MoveAllLeft(); //Reversal, need to form a new column ObjectCreate("XO-" + Number, OBJ_TEXT, 0, Time[0], Ask); if (CurrentDirection != NONE) //Not first X { //Get the previous object vertical position double pp = ObjectGet("XO-" + (Number - 1), OBJPROP_PRICE1); if (CurrentDirection == DOWN) ObjectSet("XO-" + Number, OBJPROP_PRICE1, pp - cDistance); else ObjectSet("XO-" + Number, OBJPROP_PRICE1, pp); } ObjectSetText("XO-" + Number, "o", 9, "Arial", ColorDown); Number++; if (Last != 0) { if (CurrentDirection == DOWN) Last = Last - cBoxSize; else Last = Last - cReversal; } else Last = Ask; CurrentDirection = DOWN; Print("O: ", Last); } void MoveAllRight() { Print("Moving All Right..."); for (int i = 0; i < Number; i++) { datetime pt = ObjectGet("XO-" + i, OBJPROP_TIME1); pt += Time[0] - Time[1]; ObjectSet("XO-" + i, OBJPROP_TIME1, pt); } } void MoveAllLeft() { Print("Moving All Left..."); for (int i = 0; i < Number; i++) { datetime pt = ObjectGet("XO-" + i, OBJPROP_TIME1); pt -= Time[0] - Time[1]; ObjectSet("XO-" + i, OBJPROP_TIME1, pt); } }