Implementing Custom Drawings - futures io
futures io



Implementing Custom Drawings


Discussion in MultiCharts

Updated
      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,880 views
    2. thumb_up 5 thanks given
    3. group 5 followers
    1. forum 15 posts
    2. attach_file 1 attachments




Welcome to futures io: the largest futures trading community on the planet, with well over 125,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)

 
Search this Thread
 

Implementing Custom Drawings

(login for full post details)
  #1 (permalink)
 Jasonnator 
Denver, Colorado United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, Kinetick, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 143 since Dec 2014
Thanks: 38 given, 131 received

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

Started this thread Reply With Quote

Can you help answer these questions
from other members on futures io?
Tradovate to Offer FairX Futures Commission-Free
Tradovate
Find the largest volumes in the cluster
NinjaTrader
Driving Crazy please help: MUltichart bar closing event …
MultiCharts
S&P option chain data
Python, Pandas, Matlab/R
PowerLanguage code for iceberg trading???
MultiCharts
 
 
(login for full post details)
  #2 (permalink)
 Jasonnator 
Denver, Colorado United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, Kinetick, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 143 since Dec 2014
Thanks: 38 given, 131 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.

Started this thread Reply With Quote
 
(login for full post details)
  #3 (permalink)
 Jasonnator 
Denver, Colorado United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, Kinetick, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 143 since Dec 2014
Thanks: 38 given, 131 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, 50 views)
Started this thread Reply With Quote
The following 3 users say Thank You to Jasonnator for this post:
 
(login for full post details)
  #4 (permalink)
 yiman 
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
 
(login for full post details)
  #5 (permalink)
 Jasonnator 
Denver, Colorado United States
 
Experience: Intermediate
Platform: NT8 + Custom
Broker: NT Brokerage, Kinetick, IQFeed, Interactive Brokers
Trading: ES
 
Jasonnator's Avatar
 
Posts: 143 since Dec 2014
Thanks: 38 given, 131 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.

Started this thread Reply With Quote
 
(login for full post details)
  #6 (permalink)
 yiman 
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:
 
(login for full post details)
  #7 (permalink)
 SteveW 
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

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
 
(login for full post details)
  #8 (permalink)
 yiman 
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


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
 
(login for full post details)
  #9 (permalink)
 SteveW 
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

see title

Reply With Quote
The following user says Thank You to SteveW for this post:
 
(login for full post details)
  #10 (permalink)
 jojojo 
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


Last Updated on September 9, 2016


Upcoming Webinars and Events
 

NinjaTrader Indicator Challenge!

Ongoing

Your Trading Jekyll and Hyde w/Peter Davies @ Jigsaw Trading

Elite only
 

Our 12-year anniversary w/ $$,$$$ prizes (check soon)

June
     



Copyright © 2021 by futures io, s.a., Av Ricardo J. Alfaro, Century Tower, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada), 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