Example #1
0
        //private void onKeyUp(object sender, KeyEventArgs e) { isKeyPressed=false; Print("keyup");}

        private void OnMouseDownEvent(object sender, MouseButtonEventArgs e)
        {
            if (checkForDeregister())
            {
                return;
            }

            Point cPos = chartControl.MouseDownPoint;
            int   posX = (int)ChartingExtensions.ConvertToHorizontalPixels(cPos.X - chartControl.BarWidthArray[0], chartControl.PresentationSource);
            int   slot = (int)chartControl.GetSlotIndexByX(posX);

            //if clicked on visible
            if (slot >= chartBars.FromIndex && slot <= chartBars.ToIndex)
            {
                int clicked_Bar = slot;

                if (System.Windows.Forms.Control.ModifierKeys == Keys.Shift)                 //isKeyPressed
                {
                    //isKeyPressed=false;
                    destroyForm(false);
                    createForm();
                    logForm.Show();
                }
                if (logForm.Visible)
                {
                    if (indi_or_strat != null)
                    {
                        if (indi_or_strat.BarsArray[0] != null)
                        {
                            Bars bars = indi_or_strat.BarsArray[0];

                            int    barIdx  = indi_or_strat.CurrentBars[0] - clicked_Bar - 1;                     //indi.CurrentBars[0]
                            string bn      = Library_PuvoxSoftware.Methods.barIdentifier(indi_or_strat, barIdx);
                            string bn_prev = Library_PuvoxSoftware.Methods.barIdentifier(indi_or_strat, barIdx + 1);
                            //IBar thebar = GetBarFromX(e.X);

                            string primary = (primaryDict.ContainsKey(bn) ? primaryDict[bn]             : "");

                            /*
                             * string secondary= ( secondaryDict.ContainsKey(bn_prev) ? secondaryDict[ bn_prev ]	: "" );
                             * string final_text =  (secondary == "" ? "" : secondary + nl + "<<< BarsInProgress: 0 >>>"+ nl) + primary	;
                             */
                            string warning_message = nl + "############ Warning ############" + nl + "The following BIP data is used to form the next Primary BAR." + nl + "To understand DataSeries better, read: - https://goo.gl/ScpDkN" + nl + "##############################" + nl;
                            string secondary       = (secondaryDict.ContainsKey(bn) ? warning_message + secondaryDict[bn] : "");

                            string final_text = primary + secondary;
                            textarea.Text = final_text;

                            DrawVerticalLine(bars.GetTime(clicked_Bar + 1));
                        }
                    }
                }
            }
        }
Example #2
0
        protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            // This sample should be used along side the help guide educational resource on this topic:
            // http://www.ninjatrader.com/support/helpGuides/nt8/en-us/?using_sharpdx_for_custom_chart_rendering.htm

            // Default plotting in base class. Uncomment if indicators holds at least one plot
            // in this case we would expect NOT to see the SMA plot we have as well in this sample script
            //base.OnRender(chartControl, chartScale);

            // 1.1 - SharpDX Vectors and Charting RenderTarget Coordinates

            // The SharpDX SDK uses "Vector2" objects to describe a two-dimensional point of a device (X and Y coordinates)
            SharpDX.Vector2 startPoint;
            SharpDX.Vector2 endPoint;

            // For our custom script, we need a way to determine the Chart's RenderTarget coordinates to draw our custom shapes
            // This info can be found within the NinjaTrader.Gui.ChartPanel class.
            // You can also use various chartScale and chartControl members to calculate values relative to time and price
            // However, those concepts will not be discussed or used in this sample
            // Notes:  RenderTarget is always the full ChartPanel, so we need to be mindful which sub-ChartPanel we're dealing with
            // Always use ChartPanel X, Y, W, H - as chartScale and chartControl properties WPF units, so they can be drastically different depending on DPI set
            startPoint = new SharpDX.Vector2(ChartPanel.X, ChartPanel.Y);
            endPoint   = new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, ChartPanel.Y + ChartPanel.H);

            // These Vector2 objects are equivalent with WPF System.Windows.Point and can be used interchangeably depending on your requirements
            // For convenience, NinjaTrader provides a "ToVector2()" extension method to convert from WPF Points to SharpDX.Vector2
            SharpDX.Vector2 startPoint1 = new System.Windows.Point(ChartPanel.X, ChartPanel.Y + ChartPanel.H).ToVector2();
            SharpDX.Vector2 endPoint1   = new System.Windows.Point(ChartPanel.X + ChartPanel.W, ChartPanel.Y).ToVector2();

            // SharpDX.Vector2 objects contain X/Y properties which are helpful to recalculate new properties based on the initial vector
            float width  = endPoint.X - startPoint.X;
            float height = endPoint.Y - startPoint.Y;

            // Or you can recalculate a new vector from existing vector objects
            SharpDX.Vector2 center = (startPoint + endPoint) / 2;

            // Tip: This check is simply added to prevent the Indicator dialog menu from opening as a user clicks on the chart
            // The default behavior is to open the Indicator dialog menu if a user double clicks on the indicator
            // (i.e, the indicator falls within the RenderTarget "hit testing")
            // You can remove this check if you want the default behavior implemented
            if (!IsInHitTest)
            {
                // 1.2 - SharpDX Brush Resources

                // RenderTarget commands must use a special brush resource defined in the SharpDX.Direct2D1 namespace
                // These resources exist just like you will find in the WPF/Windows.System.Media namespace
                // such as SolidColorBrushes, LienarGraidentBrushes, RadialGradientBrushes, etc.
                // To begin, we will start with the most basic "Brush" type
                // Warning:  Brush objects must be disposed of after they have been used
                SharpDX.Direct2D1.Brush areaBrushDx;
                SharpDX.Direct2D1.Brush smallAreaBrushDx;
                SharpDX.Direct2D1.Brush textBrushDx;

                // for convenience, you can simply convert a WPF Brush to a DXBrush using the ToDxBrush() extension method provided by NinjaTrader
                // This is a common approach if you have a Brush property created e.g., on the UI you wish to use in custom rendering routines
                areaBrushDx      = areaBrush.ToDxBrush(RenderTarget);
                smallAreaBrushDx = smallAreaBrush.ToDxBrush(RenderTarget);
                textBrushDx      = textBrush.ToDxBrush(RenderTarget);

                // However - it should be noted that this conversion process can be rather expensive
                // If you have many brushes being created, and are not tied to WPF resources
                // You should rather favor creating the SharpDX Brush directly:
                // Warning:  SolidColorBrush objects must be disposed of after they have been used
                SharpDX.Direct2D1.SolidColorBrush customDXBrush = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget,
                                                                                                        SharpDX.Color.DodgerBlue);

                // 1.3 - Using The RenderTarget
                // before executing chart commands, you have the ability to describe how the RenderTarget should render
                // for example, we can store the existing RenderTarget AntialiasMode mode
                // then update the AntialiasMode to be the quality of non-text primitives are rendered
                SharpDX.Direct2D1.AntialiasMode oldAntialiasMode = RenderTarget.AntialiasMode;
                RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.Aliased;

                // Note: The code above stores the oldAntialiasMode as a best practices
                // i.e., if you plan on changing a property of the RenderTarget, you should plan to set it back
                // This is to make sure your requirements to no interfere with the function of another script
                // Additionally smoothing has some performance impacts

                // Once you have defined all the necessary requirements for you object
                //  You can execute a command on the RenderTarget to draw specific shapes
                // e.g., we can now use the RenderTarget's DrawLine() command to render a line
                // using the start/end points and areaBrushDx objects defined before
                RenderTarget.DrawLine(startPoint, endPoint, areaBrushDx, 4);

                // Since rendering occurs in a sequential fashion, after you have executed a command
                // you can switch a property of the RenderTarget to meet other requirements
                // For example, we can draw a second line now which uses a different AntialiasMode
                // and the changes render on the chart for both lines from the time they received commands
                RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
                RenderTarget.DrawLine(startPoint1, endPoint1, areaBrushDx, 4);

                // 1.4 - Rendering Custom Shapes

                // SharpDX namespace consists of several shapes you can use to draw objects more complicated than lines
                // For example, we can use the RectangleF object to draw a rectangle that covers the entire chart area
                SharpDX.RectangleF rect = new SharpDX.RectangleF(startPoint.X, startPoint.Y, width, height);

                // The RenderTarget consists of two commands related to Rectangles.
                // The FillRectangle() method is used to "Paint" the area of a Rectangle
                RenderTarget.FillRectangle(rect, areaBrushDx);

                // and DrawRectangle() is used to "Paint" the outline of a Rectangle
                RenderTarget.DrawRectangle(rect, customDXBrush, 2);

                // Another example is an ellipse which can be used to draw circles
                // The ellipse center point can be used from the Vectors calculated earlier
                // The width and height an absolute 100 device pixels
                // To ensure that pixel coordinates work across all DPI devices, we use the NinjaTrader ChartingExteions methods
                // Which will convert the "100" value from WPF pixels to Device Pixels both vertically and horizontally
                int ellipseRadiusY = ChartingExtensions.ConvertToVerticalPixels(100, ChartControl.PresentationSource);
                int ellipseRadiusX = ChartingExtensions.ConvertToHorizontalPixels(100, ChartControl.PresentationSource);

                SharpDX.Direct2D1.Ellipse ellipse = new SharpDX.Direct2D1.Ellipse(center, ellipseRadiusX, ellipseRadiusY);

                // 1.5 - Complex Brush Types and Shapes
                // For this ellipse, we can use one of the more complex brush types "RadialGradientBrush"
                // Warning:  RadialGradientBrush objects must be disposed of after they have been used
                SharpDX.Direct2D1.RadialGradientBrush radialGradientBrush;

                // However creating a RadialGradientBrush requires a few more properties than SolidColorBrush
                // First, you need to define the array gradient stops the brush will eventually use
                SharpDX.Direct2D1.GradientStop[] gradientStops = new SharpDX.Direct2D1.GradientStop[2];

                // With the gradientStops array, we can describe the color and position of the individual gradients
                gradientStops[0].Color    = SharpDX.Color.Goldenrod;
                gradientStops[0].Position = 0.0f;
                gradientStops[1].Color    = SharpDX.Color.SeaGreen;
                gradientStops[1].Position = 1.0f;

                // then declare a GradientStopCollection from our render target that uses the gradientStops array defined just before
                // Warning:  GradientStopCollection objects must be disposed of after they have been used
                SharpDX.Direct2D1.GradientStopCollection gradientStopCollection =
                    new SharpDX.Direct2D1.GradientStopCollection(RenderTarget, gradientStops);

                // we also need to tell our RadialGradientBrush to match the size and shape of the ellipse that we will be drawing
                // for convenience, SharpDX provides a RadialGradientBrushProperties structure to help define these properties
                SharpDX.Direct2D1.RadialGradientBrushProperties radialGradientBrushProperties =
                    new SharpDX.Direct2D1.RadialGradientBrushProperties
                {
                    GradientOriginOffset = new SharpDX.Vector2(0, 0),
                    Center  = ellipse.Point,
                    RadiusX = ellipse.RadiusY,
                    RadiusY = ellipse.RadiusY
                };

                // we now have everything we need to create a radial gradient brush
                radialGradientBrush = new SharpDX.Direct2D1.RadialGradientBrush(RenderTarget, radialGradientBrushProperties,
                                                                                gradientStopCollection);

                // Finally, we can use this radialGradientBrush to "Paint" the area of the ellipse
                RenderTarget.FillEllipse(ellipse, radialGradientBrush);

                // 1.6 - Simple Text Rendering

                // For rendering custom text to the Chart, there are a few ways you can approach depending on your requirements
                // The most straight forward way is to "borrow" the existing chartControl font provided as a "SimpleFont" class
                // Using the chartControl LabelFont, your custom object will also change to the user defined properties allowing
                // your object to match different fonts if defined by user.

                // The code below will use the chartControl Properties Label Font if it exists,
                // or fall back to a default property if it cannot obtain that value
                NinjaTrader.Gui.Tools.SimpleFont simpleFont = chartControl.Properties.LabelFont ?? new NinjaTrader.Gui.Tools.SimpleFont("Arial", 12);

                // the advantage of using a SimpleFont is they are not only very easy to describe
                // but there is also a convenience method which can be used to convert the SimpleFont to a SharpDX.DirectWrite.TextFormat used to render to the chart
                // Warning:  TextFormat objects must be disposed of after they have been used
                SharpDX.DirectWrite.TextFormat textFormat1 = simpleFont.ToDirectWriteTextFormat();

                // Once you have the format of the font, you need to describe how the font needs to be laid out
                // Here we will create a new Vector2() which draws the font according to the to top left corner of the chart (offset by a few pixels)
                SharpDX.Vector2 upperTextPoint = new SharpDX.Vector2(ChartPanel.X + 10, ChartPanel.Y + 20);
                // Warning:  TextLayout objects must be disposed of after they have been used
                SharpDX.DirectWrite.TextLayout textLayout1 =
                    new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Globals.DirectWriteFactory,
                                                       NinjaTrader.Custom.Resource.SampleCustomPlotUpperLeftCorner, textFormat1, ChartPanel.X + ChartPanel.W,
                                                       textFormat1.FontSize);

                // With the format and layout of the text completed, we can now render the font to the chart
                RenderTarget.DrawTextLayout(upperTextPoint, textLayout1, textBrushDx,
                                            SharpDX.Direct2D1.DrawTextOptions.NoSnap);

                // 1.7 - Advanced Text Rendering

                // Font formatting and text layouts can get as complex as you need them to be
                // This example shows how to use a complete custom font unrelated to the existing user-defined chart control settings
                // Warning:  TextLayout and TextFormat objects must be disposed of after they have been used
                SharpDX.DirectWrite.TextFormat textFormat2 =
                    new SharpDX.DirectWrite.TextFormat(NinjaTrader.Core.Globals.DirectWriteFactory, "Century Gothic", FontWeight.Bold,
                                                       FontStyle.Italic, 32f);
                SharpDX.DirectWrite.TextLayout textLayout2 =
                    new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Globals.DirectWriteFactory,
                                                       NinjaTrader.Custom.Resource.SampleCustomPlotLowerRightCorner, textFormat2, 400, textFormat1.FontSize);

                // the textLayout object provides a way to measure the described font through a "Metrics" object
                // This allows you to create new vectors on the chart which are entirely dependent on the "text" that is being rendered
                // For example, we can create a rectangle that surrounds our font based off the textLayout which would dynamically change if the text used in the layout changed dynamically
                SharpDX.Vector2 lowerTextPoint = new SharpDX.Vector2(ChartPanel.W - textLayout2.Metrics.Width - 5,
                                                                     ChartPanel.Y + (ChartPanel.H - textLayout2.Metrics.Height));
                SharpDX.RectangleF rect1 = new SharpDX.RectangleF(lowerTextPoint.X, lowerTextPoint.Y, textLayout2.Metrics.Width,
                                                                  textLayout2.Metrics.Height);

                // We can draw the Rectangle based on the TextLayout used above
                RenderTarget.FillRectangle(rect1, smallAreaBrushDx);
                RenderTarget.DrawRectangle(rect1, smallAreaBrushDx, 2);

                // And render the advanced text layout using the DrawTextLayout() method
                // Note:  When drawing the same text repeatedly, using the DrawTextLayout() method is more efficient than using the DrawText()
                // because the text doesn't need to be formatted and the layout processed with each call
                RenderTarget.DrawTextLayout(lowerTextPoint, textLayout2, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap);

                // 1.8 - Cleanup
                // This concludes all of the rendering concepts used in the sample
                // However - there are some final clean up processes we should always provided before we are done

                // If changed, do not forget to set the AntialiasMode back to the default value as described above as a best practice
                RenderTarget.AntialiasMode = oldAntialiasMode;

                // We also need to make sure to dispose of every device dependent resource on each render pass
                // Failure to dispose of these resources will eventually result in unnecessary amounts of memory being used on the chart
                // Although the effects might not be obvious as first, if you see issues related to memory increasing over time
                // Objects such as these should be inspected first
                areaBrushDx.Dispose();
                customDXBrush.Dispose();
                gradientStopCollection.Dispose();
                radialGradientBrush.Dispose();
                smallAreaBrushDx.Dispose();
                textBrushDx.Dispose();
                textFormat1.Dispose();
                textFormat2.Dispose();
                textLayout1.Dispose();
                textLayout2.Dispose();
            }
        }
Example #3
0
        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Description             = @"IchimokuCloud Kinko Hyo - \Equilibrium Chart at a Glance\ - For a FULL description of this indicator and how to use it, please see:  http://www.forexabode.com/technical-analysis/ichimoku-cloud";
                Name                    = "IchimokuCloud";
                Calculate               = Calculate.OnBarClose;
                IsOverlay               = true;
                DisplayInDataBox        = true;
                DrawOnPricePanel        = true;
                DrawHorizontalGridLines = true;
                DrawVerticalGridLines   = true;
                PaintPriceMarkers       = true;
                ScaleJustification      = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                //See Help Guide for additional information.
                IsSuspendedWhileInactive = false;

                // Create default brushes
                dxmBrushes = new Dictionary <string, DXMediaMap>();

                foreach (string brushName in new string[] { "CloudAreaColorUp", "CloudAreaColorDown" })
                {
                    dxmBrushes.Add(brushName, new DXMediaMap());
                }

                DisplayCloudOnly = true;
                AdjustBarMargins = false;

                PeriodFast   = 9;
                PeriodMedium = 26;
                PeriodSlow   = 52;

                CloudColorOpacity  = 40;
                CloudAreaColorUp   = Brushes.Green;
                CloudAreaColorDown = Brushes.Red;

                CloudDisplacement = 26;

                AddPlot(Brushes.Red, "TenkanSen");
                AddPlot(Brushes.Purple, "KijunSen");
                AddPlot(Brushes.MediumBlue, "ChikouSpan");

                AddPlot(Brushes.Green, "SenkouSpanA");
                AddPlot(Brushes.Red, "SenkouSpanB");
            }
            else if (State == State.DataLoaded)
            {
                if (ChartControl != null)
                {
                    // Adjust margins
                    tmpMargin = ChartControl.Properties.BarMarginRight;
                    if (AdjustBarMargins)
                    {
                        ChartControl.Properties.BarMarginRight = ChartingExtensions.ConvertToHorizontalPixels(ChartControl.BarWidth * (CloudDisplacement + 2) * 2, ChartControl.PresentationSource);
                    }
                }
            }
            else if (State == State.Terminated)
            {
                //Reset Chart Margins
                if (ChartControl != null && tmpMargin != 0)
                {
                    ChartControl.Properties.BarMarginRight = tmpMargin;
                }
            }
        }
        //private void onKeyUp(object sender, KeyEventArgs e) { isKeyPressed=false; Print("keyup");}

        private void OnMouseDownEvent(object sender, MouseButtonEventArgs e)
        {
            log("OnMouseDownEvent1");
            if (checkForDeregister())
            {
                return;
            }

            if (indi_or_strat != null)
            {
                log("OnMouseDownEvent1-A");
                Point cPos = chartControl.MouseDownPoint;
                // Coefficient between Bar and it's margin space is 0.65
                int posX = (int)ChartingExtensions.ConvertToHorizontalPixels(cPos.X + chartControl.BarWidthArray[0] * 1.65, chartControl.PresentationSource);
                int slot = (int)chartControl.GetSlotIndexByX(posX);
                //IBar thebar = GetBarFromX(e.X);

                //if clicked on visible
                if (slot >= chartBars.FromIndex && slot <= chartBars.ToIndex)
                {
                    log("OnMouseDownEvent1-B");
                    int clicked_Bar = slot;
                    // If Shift + Click , then open form
                    if (System.Windows.Forms.Control.ModifierKeys == Keys.Shift)                     //isKeyPressed
                    {
                        //isKeyPressed=false;
                        if (logForm == null || logForm.IsDisposed)
                        {
                            createForm();
                        }
                        if (!logForm.Visible)
                        {
                            logForm.Show();
                        }
                    }
                    log("OnMouseDownEvent1-C");

                    // If By this moment, form is/was open, show values
                    if (logForm != null && logForm.Visible)
                    {
                        logForm.BringToFront();
                        log("OnMouseDownEvent1-D");
                        if (indi_or_strat.BarsArray[0] != null)
                        {
                            log("OnMouseDownEvent1-E");
                            Bars bars    = indi_or_strat.BarsArray[0];
                            int  barsAgo = indi_or_strat.CurrentBars[0] - clicked_Bar;
                            if (clicked_Bar <= 0)
                            {
                                return;
                            }
                            string bn      = Puvox_Library.Methods.barIdentifier(indi_or_strat, barsAgo);
                            string primary = (primaryDict.ContainsKey(bn) ? primaryDict[bn]             : "");

                            /*
                             * string bn_prev = clicked_Bar <= 0 ? "" :  Puvox_Library.Methods.barIdentifier( indi_or_strat, barsAgo+1 );
                             * string secondary=clicked_Bar <= 0 ? "" :  ( secondaryDict.ContainsKey(bn_prev) ? secondaryDict[ bn_prev ]	: "" );
                             */
                            string warning_message = nl + "############ Warning ############" + nl + "Typically, additional (granular) BIP data (except the first one) is used to form the next Primary BAR." + nl + "To understand DataSeries better, must read: - https://goo.gl/ScpDkN" + nl + "##############################" + nl;
                            string secondary       = (secondaryDict.ContainsKey(bn) ? warning_message + secondaryDict[bn] : "");
                            string final_text      = primary + secondary;
                            textarea.Text = final_text;
                            Puvox_Library.Methods.DrawVerticalLineBlinking(indi_or_strat, barsAgo);
                            log("OnMouseDownEvent1-F");
                        }
                    }
                }
            }
            log("OnMouseDownEvent2");
        }
        protected void MouseClicked(object sender, MouseButtonEventArgs e)

        {
            clickPoint.X = ChartingExtensions.ConvertToHorizontalPixels(e.GetPosition(ChartControl as IInputElement).X, ChartControl.PresentationSource);
            clickPoint.Y = ChartingExtensions.ConvertToVerticalPixels(e.GetPosition(ChartControl as IInputElement).Y, ChartControl.PresentationSource);

            convertedPrice = Instrument.MasterInstrument.RoundToTickSize(chartScale.GetValueByY((float)clickPoint.Y));

            convertedTime = ChartControl.GetTimeBySlotIndex((int)ChartControl.GetSlotIndexByX((int)clickPoint.X));


            if (counter == 0)
            {
                ++counter;
                ++patterncount;
                sw = File.AppendText(path);                  // Open the path for writing
                sw.Write("New Pattern,");
                Draw.TextFixed(this, "priceTime", "Click to Start", TextPosition.BottomLeft, ChartControl.Properties.ChartText,
                               ChartControl.Properties.LabelFont, Brushes.LimeGreen, Brushes.Transparent, 0);
                sw.Close();                 // Close the file to allow future calls to access the file again.
                Print("NEW PATTERN");
            }

            else if (counter == 1)
            {
                ++counter;
                sw = File.AppendText(path);                      // Open the path for writing
                sw.Write(string.Format("{0},", convertedPrice)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on X Point"), TextPosition.BottomLeft);
                sw.Close();                                      // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }

            else if (counter == 2)
            {
                ++counter;
                sw = File.AppendText(path);                      // Open the path for writing
                sw.Write(string.Format("{0},", convertedPrice)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on A Point"), TextPosition.BottomLeft);
                sw.Close();                                      // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }

            else if (counter == 3)
            {
                ++counter;
                sw = File.AppendText(path);                      // Open the path for writing
                sw.Write(string.Format("{0},", convertedPrice)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on C Point"), TextPosition.BottomLeft);
                sw.Close();                                      // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }

            else if (counter == 4)
            {
                ++counter;
                sw = File.AppendText(path);                      // Open the path for writing
                sw.Write(string.Format("{0},", convertedPrice)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on D/ENTRY Point"), TextPosition.BottomLeft);
                sw.Close();                                      // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }

            else if (counter == 5)
            {
                ++counter;
                sw = File.AppendText(path);                     // Open the path for writing
                sw.Write(string.Format("{0},", convertedTime)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on D/ENTRY Date"), TextPosition.BottomLeft);
                sw.Close();                                     // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }

            else if (counter == 6)
            {
                ++counter;
                sw = File.AppendText(path);                      // Open the path for writing
                sw.Write(string.Format("{0},", convertedPrice)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on TARGET 1"), TextPosition.BottomLeft);
                sw.Close();                                      // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }

            else if (counter == 7)
            {
                ++counter;
                sw = File.AppendText(path);                      // Open the path for writing
                sw.Write(string.Format("{0},", convertedPrice)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on MAE"), TextPosition.BottomLeft);
                sw.Close();                                      // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }

            else if (counter == 8)
            {
                ++counter;
                sw = File.AppendText(path);                     // Open the path for writing
                sw.Write(string.Format("{0},", convertedTime)); // Append a new line to the file
                Draw.TextFixed(this, "priceTime", string.Format("Click on Close Date/Time"), TextPosition.BottomLeft);
                sw.Close();                                     // Close the file to allow future calls to access the file again.
                Print(string.Format("{0},", convertedPrice));
            }


            else if (counter == 9)
            {
                counter = 0;
                sw      = File.AppendText(path);             // Open the path for writing
                sw.WriteLine("");
                Draw.TextFixed(this, "priceTime", string.Format("Pattern Complete"), TextPosition.BottomLeft);
                sw.Close();                 // Close the file to allow future calls to access the file again.
                Print("PATTERN COMPLETE");
            }



            ForceRefresh();
        }