//https://www.forexfactory.com/thread/304770-tools-for-forexhards-stairstep-breakouts-system //+------------------------------------------------------------------+ //| sqDynamicBreakoutBox.mq4 //| by Squalou, 2011.07.05 //+------------------------------------------------------------------+ #property copyright "by Squalou, 2011.07.05" #property link "http://www.forexfactory.com/showthread.php?t=302007" #define VERSION "v1.8" #define DATE "2011.07.25" /*+------------------------------------------------------------------+ * sqDynamicBreakoutBox.mq4, by Squalou, 2011.07.05: * - draws Dynamic Breakout Boxes based on consolidation areas; * - consolidation areas are defined by a minimum period of time during which * the Range of PA remained below a minimum Range value; * - Inputs: * - BoxLength and BoxTimeFrame: define the minimum duration of the congestion areas * Better than specifying a number of bars, because this will not independ * on the chart's timeframe; * - BoxRange: the Box Range in pips; * - AutoBoxRange (true/false), AutoBoxRangeDailyATRperiod(=30) and AutoBoxRangeDailyATRfactor(=0.25): * to automatically determine a the Box size based on Daily ATR, rather than a fixed size. * - BoxBufferPips: draws the Yellow and Magenta "breakout" lines at this distance from the actual Box; * * This indicator was inspired by a thread opened by "forexhard" on ForexFactory. * http://www.forexfactory.com/showthread.php?t=302007 * Thank you forexhard for this! * * - History: * * - v1.8 (2011.07.25): * added drawing of "Fib levels" for up to 9 TP targets on each side of the CZ Breakout areas; * new inputs: TP1..TP9 values: when <10, they are taken as a factor of the "Breakout Extent" (=Box extent + BufferPips), else they are in pips; * * - v1.7c (2011.07.22): more cosmetics... new inputs: "SwingLabelsColor","Fonts"; * - v1.7b (2011.07.21): * more cosmetics... added a "box continuation rectangle" on each Box (selectable color with BreakoutBoxContColor), * and price labels at the right of the last box continuation rectangle; * * - v1.7a (2011.07.20): * - added various cosmetic inputs (StatsColor,StatsBGColor,StatsCorner,BoxVerticalLineDelimiter,BoxVerticalLineColor); * added a "background" to the Stats area; * * - v1.6 (2011.07.20): * - Display each Box size in pips; * * - v1.5 (2011.07.12): * - added "AutoBoxRange" (true/false), "AutoBoxRangeDailyATRperiod"(=30) and "AutoBoxRangeDailyATRfactor"(=0.25) inputs: * when true, will use AutoBoxRangeDailyATRfactor*daily_ATR_value as the BoxRange value; * * - v1.4 (2011.07.11): * - added saving of statistical data into a CSV file saved in (mt4)/experts/files folder; * the CSV file name is on the typical model "EURUSD-sqDynamicBreakoutBox(4x60min,30p).csv" * Controlled by "CreateStatisticsFile"(true/false) input; * * - v1.3 (2011.07.08): * - added statistical data on maximum Buy/Sell expenctancy for each "Session"; * max Buys and Sells for each Session are indicated on the chart itself, * the total and average maximum pips are displayed in the upper right corner; * * - v1.2 (2011.07.07): * - added drawing of vertical lines marking the bar on which the Box initially formed; * This helps locate the Boxes compared on other indicator windows. * * - v1.1 (2011.07.06): * - added "BoxBufferPips" input, draws the Yellow and Magenta lines at this buffer away from the formed Box; * These are your real breakout lines; * * - v1.0 (2011.07.05): initial version; * //+------------------------------------------------------------------+ */ #property indicator_chart_window #property indicator_buffers 5 #property indicator_color1 Yellow // Breakout Box High Line #property indicator_width1 2 #property indicator_color2 Yellow // Breakout Box Low Line #property indicator_width2 2 #property indicator_color3 Magenta // Breakout Box High Line Continuation #property indicator_color4 Magenta // Breakout Box Low Line Continuation //+------------------------------------------------------------------+ //---- input parameters extern int BoxLength = 22; extern int BoxTimeFrame = 15; extern int BoxRange = 30; // fixed box range, when AutoBoxRange is false extern bool AutoBoxRange = true;// when true, will use AutoBoxRangeDailyATRfactor*daily_ATR_value as the BoxRange value; extern int AutoBoxRangeDailyATRperiod = 30; extern double AutoBoxRangeDailyATRfactor = 0.20; extern int BoxBufferPips = 5; // add this amount to the Box Yellow and Magenta lines extern int DaysBack = 0; // days back; 0=full history // TPs and SL levels "fib lines" settings: // when a TP is >=10, it is considered as FIXED PIPs, <10 is a factor of the box size (including bufferpips); extern double TP1 = 1.000; extern double TP2 = 1.618; extern double TP3 = 2.618; extern double TP4 = 4.236; extern double TP5 = 6.854; extern double TP6 = 0; extern double TP7 = 0; extern double TP8 = 0; extern double TP9 = 0; extern color TPLevelColor = DimGray; extern bool CreateStatisticsFile = false; extern color BreakoutBoxColor = DodgerBlue; extern color BreakoutBoxContColor = Blue; extern bool BreakoutBoxContFullColored = true; // true will draw a full rectangle rather than an "empty" rectangle extern color StatsColor = White; extern color StatsBGColor = DimGray; extern int StatsCorner = 1; // 0=upper-left, 1=upper-right, 2=lower-left, 3=lower-right extern bool BoxVerticalLineDelimiter = true; // false to remove vertival Box delimiter lines; extern color BoxVerticalLineColor = DodgerBlue; extern color SwingLabelsColor = Green; extern string Fonts = "Arial Black"; //+------------------------------------------------------------------+ //---- buffers double highBO[],lowBO[]; double highBOcont[],lowBOcont[]; double periodForMinRange[]; int _period,_minP,_maxP,_prevP; double _Range; datetime current_box_forming_time; string prefix; string strBoxRange; int BarsBack,lasttime; bool force_full_redraw; double pip; int pipMult,pipMultTab[]={1,10,1,10,1,10,100}; // multiplier to convert pips to Points; double TP[9],TPInput[9],TP_pips[9],BuyTP[9],SellTP[9]; double highBOvalue,lowBOvalue,BOExtent; double SL,SLInput; //+------------------------------------------------------------------+ int init() //+------------------------------------------------------------------+ { pipMult = pipMultTab[Digits]; pip = Point * pipMult; prefix = "sqDynBO"+BoxLength+" "+BoxTimeFrame+" "+BoxRange; strBoxRange = DoubleToStr(BoxRange,0)+" PIPS"; if (AutoBoxRange == true) strBoxRange = "ADR"+DoubleToStr(AutoBoxRangeDailyATRperiod,0)+"x"+DoubleToStr(AutoBoxRangeDailyATRfactor,2); _Range = BoxRange * pip; // convert pips to price range if (BoxTimeFrame==0) BoxTimeFrame=Period(); _period = BoxLength * BoxTimeFrame/Period(); _minP = _period; _prevP = _period; IndicatorShortName(WindowExpertName()+" "+VERSION+"("+BoxLength+"x"+BoxTimeFrame+"min,"+strBoxRange+")"); IndicatorBuffers(5); int b=-1; b++;SetIndexBuffer(b,highBO); SetIndexLabel(b,"Breakout Box High"); b++;SetIndexBuffer(b,lowBO); SetIndexLabel(b,"Breakout Box Low"); b++;SetIndexBuffer(b,highBOcont); SetIndexLabel(b,"Breakout Box High Continued"); b++;SetIndexBuffer(b,lowBOcont); SetIndexLabel(b,"Breakout Box Low Continued"); b++;SetIndexBuffer(b,periodForMinRange); SetIndexLabel(b,"periodForMinRange"); current_box_forming_time = 0; if (DaysBack==0) DaysBack=99999; BarsBack = iBarShift(NULL,0,iTime(NULL,PERIOD_D1,DaysBack)); lasttime=0; if (CreateStatisticsFile) delete_CSV(); force_full_redraw=true; //save input Factors; TPInput[1] = TP1; TPInput[2] = TP2; TPInput[3] = TP3; TPInput[4] = TP4; TPInput[5] = TP5; TPInput[6] = TP6; TPInput[7] = TP7; TPInput[8] = TP8; TPInput[9] = TP9; SLInput = SL; return(0); } int deinit() //+------------------------------------------------------------------+ { RemoveObjects(prefix); force_full_redraw=true; } //+------------------------------------------------------------------+ int start() //+------------------------------------------------------------------+ { double upper,lower; int jj; int i, limit, counted_bars=IndicatorCounted(); if (force_full_redraw) { force_full_redraw=false; lasttime=0; counted_bars=0; ArrayInitialize(highBO,EMPTY_VALUE); ArrayInitialize(lowBO,EMPTY_VALUE); ArrayInitialize(highBOcont,EMPTY_VALUE); ArrayInitialize(lowBOcont,EMPTY_VALUE); } if (lasttime==Time[0]) return; //once per Bar lasttime=Time[0]; limit = MathMax(MathMin(BarsBack,Bars-counted_bars-1),1); for (i=limit; i>=0; i--) { if (AutoBoxRange == true) {// determine the BoxRange dynamically using the Daily ATR; _Range = AutoBoxRangeDailyATRfactor * iATR(NULL,PERIOD_D1,AutoBoxRangeDailyATRperiod,iBarShift(NULL,PERIOD_D1,iTime(NULL,0,i),true)); } // get the period over which PA Range remained below BoxRange _period = GetPeriodForMinRange(i, _minP, 999, _Range, periodForMinRange[i+1]); periodForMinRange[i] = _period; upper = High[iHighest(NULL, 0, MODE_HIGH, _period, i)]; lower = Low [iLowest (NULL, 0, MODE_LOW, _period, i)]; // continue the previous Box high/low lines highBOcont[i] = highBOcont[i+1]; lowBOcont[i] = lowBOcont[i+1]; //draw a Dynamic Breakout Box when Price Range remains below BoxRange during more than BoxLength if (_period > _minP) { // Price range remained below BoxRange longer than BoxLength: // draw a new Breakout Box, or extend the Box if one is already drawing if (highBO[i+1]==EMPTY_VALUE && lowBO[i+1]==EMPTY_VALUE) { // no Box was forming: // start a new Box ONLY if a the previous Box is older than BoxLength if (highBO[i+_minP]==EMPTY_VALUE && lowBO[i+_minP]==EMPTY_VALUE) { // we can draw a new Box now // save some stats about the potential win/loss during the last "Box Session" save_statistics(true, Time[i+1], current_box_forming_time, highBOvalue, lowBOvalue); // limit the Box Range to BoxRange; // snap the Box to the extreme that is opposite of the first(oldest) candle of the Box if (High[i+_period-1]==upper) upper = lower+_Range; if (Low[i+_period-1]==lower) lower = upper-_Range; // draw High and Low Yellow lines starting from the beginning of the Box for (jj = i+_minP; jj>=i; jj--) { highBO[jj] = upper + BoxBufferPips * pip; lowBO[jj] = lower - BoxBufferPips * pip; } // make the "Box Continuation lines" look discontinued highBOcont[i+1] = EMPTY_VALUE; lowBOcont[i+1] = EMPTY_VALUE; highBOcont[i] = upper + BoxBufferPips * pip; lowBOcont[i] = lower - BoxBufferPips * pip; current_box_forming_time = Time[i+1]; // remember Box starting candle; // draw a Box where it started to form: drawBox(prefix+"trueBox"+TimeToStr(Time[i+1]), Time[i+_minP], upper, Time[i+1], lower, BreakoutBoxColor, 0, STYLE_SOLID, true, ""); drawLbl(prefix+"infoBox"+TimeToStr(Time[i+1]), DoubleToStr((upper-lower)/pip,0)+"p", Time[i+_period/2], lower - BoxBufferPips * pip, 12, Fonts, BreakoutBoxColor, 3); if (BoxVerticalLineDelimiter) drawVLine(prefix+"V"+TimeToStr(Time[i]), Time[i], BoxVerticalLineColor); } } else { // a Box was already forming: // extend it ONLY IF price did not break out already if (Low[i] >= lowBO[i+1] && High[i] <= highBO[i+1]) { // price is still inside the Box limits: extend the forming Box highBO[i] = highBO[i+1]; lowBO[i] = lowBO[i+1]; } else { // Price has broken out of the forming Box: stop the forming Box highBO[i] = EMPTY_VALUE; lowBO[i] = EMPTY_VALUE; } } } // draw a "box continuation rectangle" to show the Box limits during the whole "Session" highBOvalue = highBO[iBarShift(NULL,0,current_box_forming_time)]; lowBOvalue = lowBO[iBarShift(NULL,0,current_box_forming_time)]; BOExtent = highBOvalue-lowBOvalue; drawBox(prefix+"BoxCont"+TimeToStr(current_box_forming_time), current_box_forming_time, highBOvalue - BoxBufferPips * pip, Time[i], lowBOvalue + BoxBufferPips * pip, BreakoutBoxContColor, 0, STYLE_SOLID, BreakoutBoxContFullColored, ""); calc_TP_levels(BOExtent); draw_fibs(current_box_forming_time,Time[i]); } // update stats for the last "session" save_statistics(false, Time[i+1], current_box_forming_time, highBOvalue, lowBOvalue); // put price labels at the right of the LAST Box Breakout lines and continuation rectangle: (won't "pollute" the chart too much...) drawOrderArrow(prefix+"BoxHLbl", Time[0], highBOvalue, SYMBOL_RIGHTPRICE, indicator_color3); drawOrderArrow(prefix+"BoxLLbl", Time[0], lowBOvalue, SYMBOL_RIGHTPRICE, indicator_color4); if (BoxBufferPips!=0) { drawOrderArrow(prefix+"BoxContHLbl", Time[0], highBOvalue- BoxBufferPips * pip, SYMBOL_RIGHTPRICE, BreakoutBoxContColor); drawOrderArrow(prefix+"BoxContLLbl", Time[0], lowBOvalue+ BoxBufferPips * pip, SYMBOL_RIGHTPRICE, BreakoutBoxContColor); } return(0); } void calc_TP_levels(double BOExtent) { int i; //restore input Factors; for (i=1; i<=9; i++) TP[i] = TPInput[i]; for (i=1; i<=9; i++) calc_TP(i, BOExtent); } void calc_TP(int i, double BOExtent) { if(BOExtent==0) return; // when a Factor is >=10, it is considered as FIXED PIPs rather than a Factor of the box size; if (TP[i] < 10) TP_pips[i] = BOExtent*TP[i]/pip; else { TP_pips[i] = TP[i]; TP[i] = TP_pips[i]*pip/BOExtent; } BuyTP[i] = NormalizeDouble(highBOvalue + TP_pips[i]*pip,Digits); SellTP[i] = NormalizeDouble(lowBOvalue - TP_pips[i]*pip,Digits); } //-------------------------------------------------------------------------------------- void draw_fibs(datetime box_forming_time, datetime current_time) //-------------------------------------------------------------------------------------- { double fib_time2 = iTime(NULL,0,iBarShift(NULL,0,box_forming_time)+(iBarShift(NULL,0,current_time)-iBarShift(NULL,0,box_forming_time))/10); // Fibs extend to 10*(time2-time1) // draw "fib" lines for entry+stop+TP levels: string objname = prefix+"Fibo-" + box_forming_time; if (ObjectFind(objname) < 0) { ObjectCreate(objname,OBJ_FIBO,0,box_forming_time,lowBOvalue,fib_time2,highBOvalue); ObjectSet(objname,OBJPROP_RAY,false); ObjectSet(objname,OBJPROP_LEVELCOLOR,TPLevelColor); ObjectSet(objname,OBJPROP_FIBOLEVELS,32); ObjectSet(objname,OBJPROP_LEVELSTYLE,STYLE_SOLID); _SetFibLevel(objname,0,0.0,"TPO & 1st Entry Buy= %$"); _SetFibLevel(objname,1,1.0,"TPO & 1st Entry Sell= %$"); _SetFibLevel(objname,2,-TP[1], "%$(+"+DoubleToStr(TP_pips[1],0)+"p)"); _SetFibLevel(objname,3,1+TP[1],"%$(+"+DoubleToStr(TP_pips[1],0)+"p)"); for (int i=2; i<=9; i++) { if (TP[i]!=0) { _SetFibLevel(objname,2*i, -TP[i], "%$(+"+DoubleToStr(TP_pips[i],0)+"p)"); _SetFibLevel(objname,2*i+1,1+TP[i],"%$(+"+DoubleToStr(TP_pips[i],0)+"p)"); } } } else { // already exists: just move the right end to the "current_time" position ObjectMove(objname, 1, fib_time2,highBOvalue); } } //+------------------------------------------------------------------+ void _SetFibLevel(string objname, int level, double value, string description) //+------------------------------------------------------------------+ { ObjectSet(objname,OBJPROP_FIRSTLEVEL+level,value); ObjectSetFiboDescription(objname,level,description); } //+------------------------------------------------------------------+ int GetPeriodForMinRange(int shift, int MinP, int MaxP, double MinRange, int prevP) //+------------------------------------------------------------------+ { int P; double range; // calc P so that the Price Range (=Hi-Lo) remains in a "reasonably large value" over the P P=prevP; // start with previous P if (PMaxP) P=MaxP; if (_get_range(P,shift) > MinRange) {//range is OK for this P value: try shorter P values for (; P>=MinP; P--) { if (_get_range(P,shift) <= MinRange) return(P+1);//previous P value was the limit } return(P); } //try higher P values for (P=prevP+1; P MinRange) return(P); } return(MaxP); } double _get_range(int period, int shift) { return(High[iHighest(NULL,0,MODE_HIGH,period,shift)] - Low[iLowest(NULL,0,MODE_LOW,period,shift)]); } //-------------------------------------------------------------------------------------- void save_statistics(bool new_box, datetime current_time, datetime box_forming_time, double high_breakout_value, double low_breakout_value) //-------------------------------------------------------------------------------------- { // save some stats about the potential win/loss during the last "Box Session" int i,highest_bar,lowest_bar,period; double highest_price,lowest_price,best_buy=0,best_sell=0; if (box_forming_time == 0) return; // no box formed yet: no statistics int box_forming_shift = iBarShift(NULL,0,box_forming_time); int current_shift = iBarShift(NULL,0,current_time); period = box_forming_shift - current_shift + 1; highest_bar = iHighest(NULL,0,MODE_HIGH,period,current_shift); highest_price = High[highest_bar]; best_buy = 0; if (highest_price > high_breakout_value) { // PA did breakout the top of the box: BUY was triggered best_buy = (highest_price - high_breakout_value) / pip; // mark the absolute best Buy extension on the chart //drawOrderArrow(prefix+TimeToStr(Time[highest_bar])+"SwingHigh:"+DoubleToStr(best_buy,0)+"p", Time[highest_bar], highest_price, SYMBOL_CHECKSIGN, SwingLabelsColor); drawLbl(prefix+"SwingHigh"+TimeToStr(box_forming_time), DoubleToStr(best_buy,0)+"p", Time[highest_bar], highest_price+10*pip, 12, Fonts, SwingLabelsColor, 3); } lowest_bar = iLowest(NULL,0,MODE_LOW,period,current_shift); lowest_price = Low[lowest_bar]; best_sell = 0; if (lowest_price < low_breakout_value) { // PA did breakout the bottom of the box: SELL was triggered best_sell = (low_breakout_value - lowest_price) / pip; // mark the absolute best Sell extension on the chart //drawOrderArrow(prefix+TimeToStr(Time[lowest_bar])+"SwingLow:"+DoubleToStr(best_sell,0)+"p", Time[lowest_bar], lowest_price, SYMBOL_CHECKSIGN, SwingLabelsColor); drawLbl(prefix+"SwingLow"+TimeToStr(box_forming_time), DoubleToStr(best_sell,0)+"p", Time[lowest_bar], lowest_price, 12, Fonts, SwingLabelsColor, 3); } // update CSV file and totals only at each new bar if (!new_box) return; // save the best result in the database if (CreateStatisticsFile) save_trades_in_CSV(current_time, box_forming_time, best_buy, best_sell, (high_breakout_value-low_breakout_value)/pip); // Compute the average BestBuy and BestSell expectation per Session double sum_buy=0,sum_sell=0,result; int num_buy=0,num_sell=0,num_boxes=0; string o; for (i = ObjectsTotal(EMPTY); i >= 0; i--) { o = ObjectName(i); //Print(o); if (StringFind(o, prefix+"SwingHigh", 0) > -1) { result = StrToInteger(StringSubstr(ObjectDescription(o),0,StringLen(ObjectDescription(o))-1)); if (result>0) { sum_buy += result; num_buy++; } } if (StringFind(o, prefix+"SwingLow", 0) > -1) { result = StrToInteger(StringSubstr(ObjectDescription(o),0,StringLen(ObjectDescription(o))-1)); if (result>0) { sum_sell +=result; num_sell++; } } if (StringFind(o, prefix+"trueBox", 0) > -1) { num_boxes++; } } // Display the total number of Buys and Sells, total maximum pips, and average pips per session int y=0,dy=20,x=10; y+=dy;drawFixedLbl(prefix+"infoBox", "Box="+strBoxRange, StatsCorner, x, y, 10, "Arial", StatsColor, false); drawFixedLbl(prefix+"numBoxbg"+y, "ggggggg", StatsCorner, x-5, y-5, 16, "Webdings", StatsBGColor, true); y+=dy;drawFixedLbl(prefix+"numBox", DoubleToStr(num_boxes,0)+" Boxes", StatsCorner, x, y, 10, "Arial", StatsColor, false); drawFixedLbl(prefix+"numBoxbg"+y, "ggggggg", StatsCorner, x-5, y-5, 16, "Webdings", StatsBGColor, true); y+=dy;drawFixedLbl(prefix+"ttB", "Total:"+DoubleToStr(num_buy,0)+" Buys="+DoubleToStr(sum_buy,0)+"p", StatsCorner, x, y, 10, "Arial", StatsColor, false); drawFixedLbl(prefix+"numBoxbg"+y, "ggggggg", StatsCorner, x-5, y-5, 16, "Webdings", StatsBGColor, true); y+=dy;if(num_buy!=0)drawFixedLbl(prefix+"ttAvgB", "Avg Buys="+DoubleToStr(sum_buy/num_buy,0)+"p", StatsCorner, x, y, 10, "Arial", StatsColor, false); drawFixedLbl(prefix+"numBoxbg"+y, "ggggggg", StatsCorner, x-5, y-5, 16, "Webdings", StatsBGColor, true); y+=dy;drawFixedLbl(prefix+"ttS", "Total:"+DoubleToStr(num_sell,0)+" Sells="+DoubleToStr(sum_sell,0)+"p", StatsCorner, x, y, 10, "Arial", StatsColor, false); drawFixedLbl(prefix+"numBoxbg"+y, "ggggggg", StatsCorner, x-5, y-5, 16, "Webdings", StatsBGColor, true); y+=dy;if(num_sell!=0)drawFixedLbl(prefix+"ttAvgS", "Avg Sells="+DoubleToStr(sum_sell/num_sell,0)+"p", StatsCorner, x, y, 10, "Arial", StatsColor, false); drawFixedLbl(prefix+"numBoxbg"+y, "ggggggg", StatsCorner, x-5, y-5, 16, "Webdings", StatsBGColor, true); } //-------------------------------------------------------------------------------------- void save_trades_in_CSV(datetime current_time, datetime box_forming_time, double best_buy, double best_sell, int box_range) //-------------------------------------------------------------------------------------- { // save the best results in a CSV file string filename = Symbol()+"-"+WindowExpertName()+"-"+AccountServer()+"-"+Period()+"("+BoxLength+"x"+BoxTimeFrame+"min,"+strBoxRange+"p)"+".CSV"; int f; f=FileOpen(filename, FILE_CSV|FILE_READ|FILE_WRITE, ";"); FileSeek(f, 0, SEEK_END); if(f>0) { FileWrite(f ,WindowExpertName() ,BoxLength ,BoxTimeFrame ,box_range ,"BO session=" ,TimeToStr(box_forming_time) ,TimeToStr(current_time) ,"BestBuy=" ,DoubleToStr(best_buy,0) ,"p" ,"BestSell=" ,DoubleToStr(best_sell,0) ,"p" ); FileClose(f); } } //-------------------------------------------------------------------------------------- void delete_CSV() //-------------------------------------------------------------------------------------- { string filename = Symbol()+"-"+WindowExpertName()+"-"+AccountServer()+"-"+Period()+"("+BoxLength+"x"+BoxTimeFrame+"min,"+strBoxRange+"p)"+".CSV"; int f; f=FileOpen(filename, FILE_CSV|FILE_WRITE, ";"); FileClose(f); } //-------------------------------------------------------------------------------------- void drawFixedLbl(string objname, string s, int Corner, int DX, int DY, int FSize, string Font, color c, bool bg) //-------------------------------------------------------------------------------------- { if (ObjectFind(objname) < 0) ObjectCreate(objname, OBJ_LABEL, 0, 0, 0); ObjectSet(objname, OBJPROP_CORNER, Corner); ObjectSet(objname, OBJPROP_XDISTANCE, DX); ObjectSet(objname, OBJPROP_YDISTANCE, DY); ObjectSet(objname,OBJPROP_BACK, bg); ObjectSetText(objname, s, FSize, Font, c); } // drawFixedLbl //-------------------------------------------------------------------------------------- void drawLbl(string objname, string s, int LTime, double LPrice, int FSize, string Font, color c, int width) //-------------------------------------------------------------------------------------- { if (ObjectFind(objname) < 0) { ObjectCreate(objname, OBJ_TEXT, 0, LTime, LPrice); } else { if (ObjectType(objname) == OBJ_TEXT) { ObjectSet(objname, OBJPROP_TIME1, LTime); ObjectSet(objname, OBJPROP_PRICE1, LPrice); } } ObjectSet(objname, OBJPROP_FONTSIZE, FSize); ObjectSetText(objname, s, FSize, Font, c); } /* drawLbl*/ //+------------------------------------------------------------------ void drawOrderArrow(string name, datetime t, double price, int arrowcode, color c) //+------------------------------------------------------------------ { if (ObjectFind(name) < 0) ObjectCreate(name, OBJ_ARROW, 0, t, price); else ObjectMove(name, 0, t, price); ObjectSet(name, OBJPROP_ARROWCODE, arrowcode); ObjectSet(name, OBJPROP_COLOR, c); } //-------------------------------------------------------------------------------------- void drawBox (string objname, datetime tStart, double vStart, datetime tEnd, double vEnd, color c, int width, int style, bool bg, string comment) //-------------------------------------------------------------------------------------- { if (ObjectFind(objname) == -1) { ObjectCreate(objname, OBJ_RECTANGLE, 0, tStart,vStart,tEnd,vEnd); } else { ObjectSet(objname, OBJPROP_TIME1, tStart); ObjectSet(objname, OBJPROP_TIME2, tEnd); ObjectSet(objname, OBJPROP_PRICE1, vStart); ObjectSet(objname, OBJPROP_PRICE2, vEnd); } ObjectSet(objname,OBJPROP_COLOR, c); ObjectSet(objname, OBJPROP_BACK, bg); ObjectSet(objname, OBJPROP_WIDTH, width); ObjectSet(objname, OBJPROP_STYLE, style); //ObjectSetText(objname, comment); } /* drawBox */ //+------------------------------------------------------------------ void drawVLine(string objname, int time, color c, int style=STYLE_SOLID, int width=0, int win=0) //+------------------------------------------------------------------ { ObjectCreate(objname, OBJ_VLINE, win, time, 0); ObjectSet(objname, OBJPROP_COLOR, c); ObjectSet(objname, OBJPROP_STYLE, style); ObjectSet(objname, OBJPROP_WIDTH, width); } //-------------------------------------------------------------------------------------- void RemoveObjects(string prefix) //-------------------------------------------------------------------------------------- { int i; string objname; for (i = ObjectsTotal(); i >= 0; i--) { objname = ObjectName(i); if (StringFind(objname, prefix, 0) > -1) ObjectDelete(objname); } } /* RemoveObjects*/ //+------------------------------------------------------------------+