Implementing Custom Drawings - futures io
futures io futures trading



Implementing Custom Drawings


Discussion in MultiCharts

Updated by jplourd
      Top Posters
    1. looks_one Jasonnator with 7 posts (3 thanks)
    2. looks_two yiman with 3 posts (1 thanks)
    3. looks_3 jplourd with 3 posts (0 thanks)
    4. looks_4 SteveW with 2 posts (1 thanks)
    1. trending_up 3,287 views
    2. thumb_up 5 thanks given
    3. group 5 followers
    1. forum 15 replies
    2. attach_file 1 attachments




Welcome to futures io: the largest futures trading community on the planet, with well over 100,000 members
  • Genuine reviews from real traders, not fake reviews from stealth vendors
  • Quality education from leading professional traders
  • We are a friendly, helpful, and positive community
  • We do not tolerate rude behavior, trolling, or vendors advertising in posts
  • We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community.  It's free and simple.

-- Big Mike, Site Administrator

(If you already have an account, login at the top of the page)

 
Thread Tools Search this Thread
 

Implementing Custom Drawings

  #1 (permalink)
Jacksonville, Florida United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 75 since Dec 2014
Thanks: 21 given, 49 received

Implementing Custom Drawings

I have recently switched to MultiCharts and so far like the platform except for the drawing tools. One of my systems is based on patterns but there's no elegant way to draw a triangle or XABCD pattern in MultiCharts.

I started looking at the implementation of MC drawings located in the PLTypes.dll file and found the Arrow, TrendLine, and Text objects. I called MC support and asked if extending the built in drawing tools by modifying this file was in any way against their EULA. I also specifically asked about decompiling and they said it is not against the EULA as long as I have a license and the file in question is not obfuscated.

I pulled apart the dll and first looked in EPlotShapes.cs and added Triangle to the enum list.
Then I copied all of the related TrendLine files and modified the following files so as to support a triangle shape:

ITriangleObject.cs (added 3 ChartPoint properties: pointOne, pointTwo, pointThree)
ITriangleContainer.cs (Added 3 Create functions to support 3 ChartPoint objects)
Triangle.cs (added 3 ChartPoint properties, added a Height property)
TriangleCreator.cs (same as ITriangleContainer.cs)
TriangleObjectException.cs (basic renaming from intial file copying)

I backed up ActiveObject.dll, ATCenterProxy.interop.dll, PLTypes.xml, and PLTypes.dll then copied the new files into the installation folder. Here's the kicker, it worked. However, comma, the enum Triangle does not show up in MC's built in editor intellisense but DOES in visual studio. Booyah, or so I thought.


Here's where I could use some help:
The biggest rub is Triangle doesn't show up when right clicking on a chart on the Insert Drawing submenu. That effectively makes it only usable via code which is ok but being able to use it via the Insert Drawing submenu would be great.

Jason

Reply With Quote

Can you help answer these questions
from other members on futures io?
Convert NinjaTrader NT7 indicator to Tradestation EasyLanguage and RADARSCREEN
Platforms and Indicators
Issue meeting order entry conditions
Elite Automated NinjaTrader Trading
Last 5 minutes Label
ThinkOrSwim
Moving average with Lag reduction
NinjaTrader
Linux?
ThinkOrSwim
 
 
  #2 (permalink)
Jacksonville, Florida United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 75 since Dec 2014
Thanks: 21 given, 49 received

Everything compiles but I ran into a bit of a problem with PLStudiesProxy.dll where the actual drawing logic needs to be. I am working with MultiCharts and hopefully they will allow me to implement this for them so everyone can have a triangle tool.

Reply With Quote
 
  #3 (permalink)
Jacksonville, Florida United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 75 since Dec 2014
Thanks: 21 given, 49 received


So MC basically came back and said that implementing this idea would require "profound" changes in MC. I ended up using tool bar buttons with custom functionality underneath. It's not optimized or uber efficient but it works. I uploaded while I was still tinkering but it should give anyone interested a decent place to start. Code attached...

StartCalc function
 
Code
        protected override void StartCalc()
        {
            if (!toolBarEnabled)
            {
                toolBarEnabled = true;
                ChartToolBar.AccessToolBar(toolBar =>
                {
                    var label = new Label()
                    {
                        Text = "Advanced Patterns",
                        TextAlign = ContentAlignment.MiddleCenter
                    };

                    buttonTriangle = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Draw Triangle",
                        Enabled = true
                    };

                    buttonPattern = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Draw Pattern",
                        Enabled = true
                    };

                    buttonClear = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Clear Points"
                    };

                    buttonRemoveAll = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Remove All"
                    };

                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(label));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonTriangle));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonPattern));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonClear));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonRemoveAll));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(pointCountLabel));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    buttonTriangle.Click += OnTriangleClick;
                    buttonPattern.Click += OnPatternClick;
                    buttonClear.Click += OnClearButtonClick;
                    buttonClear.Click += OnRemoveAllButtonClick;
                });
            }


        private void AddItem2ToolStrip(ToolStrip toolBar, ToolStripItem item)
        {
            item.Tag = this;
            toolBar.Items.Add(item);
        }
        }
I wanted to draw shapes interactively so I am handling mouse clicks. Don't foget to add [MouseEvents(true), SameAsSymbol(true), RecoverDrawings(false)]
 
Code
        protected override void OnMouseEvent(MouseClickArgs arg)
        {
            base.OnMouseEvent(arg);
            try
            {
                switch (arg.buttons)
                {
                    case MouseButtons.Left:
                        {
                            MouseClick = arg;
                            if (!buttonTriangle.Enabled)
                            {
                                pointList.Add(ClickToChartPoint(arg));
                                OnDrawClick();
                                if (pointList.Count == 3)
                                {
                                    _validTriangle = true;
                                    DrawTriangle(pointList);
                                    ResetTriangleButton();
                                }
                            }
                            if (!buttonPattern.Enabled)
                            {
                                pointList.Add(ClickToChartPoint(arg));
                                OnDrawClick();
                                if (pointList.Count == 5)
                                {
                                    DrawPattern(pointList);
                                    ResetPatternButton();
                                }
                            }
                            break;
                        }

                    case MouseButtons.Right:
                        {
                            break;
                        }

                    default:
                        break;
                }
            }
            catch (Exception e)
            {
            }
        }

And here is how I am drawing a triangle
 
Code
private void DrawTriangle(List<ChartPoint> chartPoints)
        {
            try
            {
                DrwTrendLine.Create(chartPoints[0], chartPoints[1]);
                DrwTrendLine.Active.Color = myPen.Color;
                DrwTrendLine.Active.Size = (int)myPen.Width;
                DrwTrendLine.Create(chartPoints[1], chartPoints[2]);
                DrwTrendLine.Active.Color = myPen.Color;
                DrwTrendLine.Active.Size = (int)myPen.Width;
                DrwTrendLine.Create(chartPoints[2], chartPoints[0]);
                DrwTrendLine.Active.Color = myPen.Color;
                DrwTrendLine.Active.Size = (int)myPen.Width;

                CustomDraw(_context);

                ResetTriangleButton(); // reenable to triangle button
                pointList.Clear(); // don't need the points anymore
                OnDrawClick(); // just updates a label on the toolbar (for testing mostly)

                _validTriangle = true;
                requireAdd = true;
            }
            catch (Exception e)
            {
                Alerts.Alert("Error in DrawTriangle: {0}", e.Message);
                ResetTriangleButton();
                pointList.Clear();
                OnDrawClick();
            }
        }

        // helper draw function
        private void CustomDraw(DrawContext dc)
        {
            try
            {
                var pointFs = new List<PointF>();
                var path = new GraphicsPath();

                foreach (var chartPoint in pointList)
                {
                    pointFs.Add(ChartCustomDraw.Environment.ChartPoint2Point(chartPoint));
                }

                float b = pointFs[0].X;
                int bn = (int)b;

                pointFs.Add(ChartCustomDraw.Environment.ChartPoint2Point(pointList[0]));
                //dc.graphics.InterpolationMode = InterpolationMode.Low;

                path.AddLines(pointFs.ToArray());

                dc.graphics.DrawPath(myPen, path);
                //dc.graphics.DrawLines(myPen, pointFs.ToArray());

                if (requireAdd)
                {
                    requireAdd = false;
                    graphicPaths.Add(path);
                }
            }
            catch (Exception)
            {
            }
        }
My Draw function, pretty simple
 
Code
private DrawContext _context;
public void Draw(DrawContext context, EDrawPhases phase)
        {
            _context = context;
            //CustomDraw(context);
        }

Attached Files
Register to download File Type: cs __AdvancedPatterns.Indicator.CS (14.3 KB, 48 views)
Reply With Quote
The following 3 users say Thank You to Jasonnator for this post:
 
  #4 (permalink)
London
 
Experience: Intermediate
Platform: ninjatrader, multicharts, MT4
Broker: IB, PFG Best
Trading: 6E, EMD, TF
 
Posts: 258 since Jul 2009
Thanks: 110 given, 152 received

how do i use this in multicharts please. This would be agreat addition for MC as i use triangles alot.

Cheers




Jasonnator View Post
So MC basically came back and said that implementing this idea would require "profound" changes in MC. I ended up using tool bar buttons with custom functionality underneath. It's not optimized or uber efficient but it works. I uploaded while I was still tinkering but it should give anyone interested a decent place to start. Code attached...

StartCalc function
 
Code
        protected override void StartCalc()
        {
            if (!toolBarEnabled)
            {
                toolBarEnabled = true;
                ChartToolBar.AccessToolBar(toolBar =>
                {
                    var label = new Label()
                    {
                        Text = "Advanced Patterns",
                        TextAlign = ContentAlignment.MiddleCenter
                    };

                    buttonTriangle = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Draw Triangle",
                        Enabled = true
                    };

                    buttonPattern = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Draw Pattern",
                        Enabled = true
                    };

                    buttonClear = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Clear Points"
                    };

                    buttonRemoveAll = new Button
                    {
                        Dock = DockStyle.Fill,
                        Text = "Remove All"
                    };

                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(label));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonTriangle));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonPattern));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonClear));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(buttonRemoveAll));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    AddItem2ToolStrip(toolBar, new ToolStripControlHost(pointCountLabel));
                    AddItem2ToolStrip(toolBar, new ToolStripSeparator());
                    buttonTriangle.Click += OnTriangleClick;
                    buttonPattern.Click += OnPatternClick;
                    buttonClear.Click += OnClearButtonClick;
                    buttonClear.Click += OnRemoveAllButtonClick;
                });
            }


        private void AddItem2ToolStrip(ToolStrip toolBar, ToolStripItem item)
        {
            item.Tag = this;
            toolBar.Items.Add(item);
        }
        }
I wanted to draw shapes interactively so I am handling mouse clicks. Don't foget to add [MouseEvents(true), SameAsSymbol(true), RecoverDrawings(false)]
 
Code
        protected override void OnMouseEvent(MouseClickArgs arg)
        {
            base.OnMouseEvent(arg);
            try
            {
                switch (arg.buttons)
                {
                    case MouseButtons.Left:
                        {
                            MouseClick = arg;
                            if (!buttonTriangle.Enabled)
                            {
                                pointList.Add(ClickToChartPoint(arg));
                                OnDrawClick();
                                if (pointList.Count == 3)
                                {
                                    _validTriangle = true;
                                    DrawTriangle(pointList);
                                    ResetTriangleButton();
                                }
                            }
                            if (!buttonPattern.Enabled)
                            {
                                pointList.Add(ClickToChartPoint(arg));
                                OnDrawClick();
                                if (pointList.Count == 5)
                                {
                                    DrawPattern(pointList);
                                    ResetPatternButton();
                                }
                            }
                            break;
                        }

                    case MouseButtons.Right:
                        {
                            break;
                        }

                    default:
                        break;
                }
            }
            catch (Exception e)
            {
            }
        }

And here is how I am drawing a triangle
 
Code
private void DrawTriangle(List<ChartPoint> chartPoints)
        {
            try
            {
                DrwTrendLine.Create(chartPoints[0], chartPoints[1]);
                DrwTrendLine.Active.Color = myPen.Color;
                DrwTrendLine.Active.Size = (int)myPen.Width;
                DrwTrendLine.Create(chartPoints[1], chartPoints[2]);
                DrwTrendLine.Active.Color = myPen.Color;
                DrwTrendLine.Active.Size = (int)myPen.Width;
                DrwTrendLine.Create(chartPoints[2], chartPoints[0]);
                DrwTrendLine.Active.Color = myPen.Color;
                DrwTrendLine.Active.Size = (int)myPen.Width;

                CustomDraw(_context);

                ResetTriangleButton(); // reenable to triangle button
                pointList.Clear(); // don't need the points anymore
                OnDrawClick(); // just updates a label on the toolbar (for testing mostly)

                _validTriangle = true;
                requireAdd = true;
            }
            catch (Exception e)
            {
                Alerts.Alert("Error in DrawTriangle: {0}", e.Message);
                ResetTriangleButton();
                pointList.Clear();
                OnDrawClick();
            }
        }

        // helper draw function
        private void CustomDraw(DrawContext dc)
        {
            try
            {
                var pointFs = new List<PointF>();
                var path = new GraphicsPath();

                foreach (var chartPoint in pointList)
                {
                    pointFs.Add(ChartCustomDraw.Environment.ChartPoint2Point(chartPoint));
                }

                float b = pointFs[0].X;
                int bn = (int)b;

                pointFs.Add(ChartCustomDraw.Environment.ChartPoint2Point(pointList[0]));
                //dc.graphics.InterpolationMode = InterpolationMode.Low;

                path.AddLines(pointFs.ToArray());

                dc.graphics.DrawPath(myPen, path);
                //dc.graphics.DrawLines(myPen, pointFs.ToArray());

                if (requireAdd)
                {
                    requireAdd = false;
                    graphicPaths.Add(path);
                }
            }
            catch (Exception)
            {
            }
        }
My Draw function, pretty simple
 
Code
private DrawContext _context;
public void Draw(DrawContext context, EDrawPhases phase)
        {
            _context = context;
            //CustomDraw(context);
        }


Reply With Quote
 
  #5 (permalink)
Jacksonville, Florida United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 75 since Dec 2014
Thanks: 21 given, 49 received

You create a new indicator and modify the shell with the code in this post. The indicator will initiate a tool bar which is where the custom drawing tools are located. This is very beta and is more of a proof of concept. It can (and should) be significantly improved with try/catch and other error checking. The mouse events are also not very efficient but do work. It is a little quirky in that you have to do things like click in the chart, then click your points. If you can step through with a debugger (attach to process), it will help you understand how things are working.

Reply With Quote
 
  #6 (permalink)
London
 
Experience: Intermediate
Platform: ninjatrader, multicharts, MT4
Broker: IB, PFG Best
Trading: 6E, EMD, TF
 
Posts: 258 since Jul 2009
Thanks: 110 given, 152 received


Jasonnator View Post
You create a new indicator and modify the shell with the code in this post. The indicator will initiate a tool bar which is where the custom drawing tools are located. This is very beta and is more of a proof of concept. It can (and should) be significantly improved with try/catch and other error checking. The mouse events are also not very efficient but do work. It is a little quirky in that you have to do things like click in the chart, then click your points. If you can step through with a debugger (attach to process), it will help you understand how things are working.

Thanks

Reply With Quote
The following user says Thank You to yiman for this post:
 
  #7 (permalink)
Vancouver, BC, Canada
 
Experience: Intermediate
Platform: Ninja
Broker: Optimus/Rithmic
Trading: ES
 
SteveW's Avatar
 
Posts: 13 since Jan 2011
Thanks: 50 given, 32 received

draw shaded box

MC.NET 9.1 -- Has anyone found a way to draw a shaded geometric shape (polygon... whatever) anchored at X,Y that will scroll with prices and not disappear when scrolling? I can draw a trendline or group of them to form the outline of a box and it will scroll with prices and not disappear, but holy cow batman I'm stumped on getting a shaded rectangle to have the same behavior.

-steve

Reply With Quote
 
  #8 (permalink)
London
 
Experience: Intermediate
Platform: ninjatrader, multicharts, MT4
Broker: IB, PFG Best
Trading: 6E, EMD, TF
 
Posts: 258 since Jul 2009
Thanks: 110 given, 152 received

geometric shapes


SteveW View Post
MC.NET 9.1 -- Has anyone found a way to draw a shaded geometric shape (polygon... whatever) anchored at X,Y that will scroll with prices and not disappear when scrolling? I can draw a trendline or group of them to form the outline of a box and it will scroll with prices and not disappear, but holy cow batman I'm stumped on getting a shaded rectangle to have the same behavior.

-steve



I made a request in 2010 so if you are lucky and you make the request now it might be ready for MC.net in 2020 :-)
All you MC or MC net users please get onto the project management forum and add your name to the list of people who want the ability to draw triangles.

Reply With Quote
 
  #9 (permalink)
Vancouver, BC, Canada
 
Experience: Intermediate
Platform: Ninja
Broker: Optimus/Rithmic
Trading: ES
 
SteveW's Avatar
 
Posts: 13 since Jan 2011
Thanks: 50 given, 32 received

colony on Mars before shaded rectangle on MC.NET

see title

Reply With Quote
The following user says Thank You to SteveW for this post:
 
  #10 (permalink)
FrankfurtGermany
 
Experience: Beginner
Platform: Tradestation
 
Posts: 24 since Oct 2010
Thanks: 3 given, 6 received


I got an error . Toolbar can not be build.

Reply With Quote



futures io Trading Community Platforms and Indicators MultiCharts > Implementing Custom Drawings




Upcoming Webinars and Events
 

Free BloodHound Licenses to everyone!

June
 

Every journal equals ten meals for the hungry

June
     



Copyright © 2020 by futures io, s.a., Av Ricardo J. Alfaro, Century Tower, Panama, +507 833-9432, info@futures.io
All information is for educational use only and is not investment advice.
There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
no new posts