MultiCharts .NET Programming Guide

Questions about MultiCharts .NET and user contributed studies.
User avatar
Dave Masalov
Posts: 1712
Joined: 16 Apr 2010
Has thanked: 51 times
Been thanked: 489 times

MultiCharts .NET Programming Guide

Postby Dave Masalov » 18 Apr 2013

Dear Users,

We have released MultiCharts .NET Programming Guide. The new Guide describes the process of developing and applying studies in MultiCharts .NET. It will help you build and debug your custom studies in MultiCharts .NET.

Please follow this link to download MultiCharts .NET Programming Guide: https://www.multicharts.com/downloads/M ... e-v1.0.pdf

MultiCharts Team

User avatar
Laurentius
Posts: 90
Joined: 01 Jan 2011
Location: Europe
Has thanked: 138 times
Been thanked: 36 times

Re: MultiCharts .NET Programming Guide

Postby Laurentius » 18 Apr 2013

Big time thanks Dave!

horned1
Posts: 1
Joined: 04 Apr 2013
Has thanked: 2 times

Re: MultiCharts .NET Programming Guide

Postby horned1 » 18 Apr 2013

Great work guys, looking forward to learning C# in MC.Net

/horned1

mfalme
Posts: 4
Joined: 04 Apr 2013

Re: MultiCharts .NET Programming Guide

Postby mfalme » 19 Apr 2013

Thanks for the guide. quick question about the Itrade Interface. In the guide pg 46 we have the double profit member, and commission which I cannot find in the code. see below for the Itrade from the code. pls clarify

public interface ITrade
{
double CommissionValue { get; } – commission of the trade
ITradeOrder EntryOrder { get; } – the order, that opened the trade - entry
ITradeOrder ExitOrder { get; }– the order, that closed the trade - exit
bool IsLong { get; } – Means, that the entry was Buy (true) or SellShort (false)
bool IsOpen { get; } – Means, that the entry was not closed yet
double Profit { get; } – OpenPL, if the trade is opend or TradeProfit – if closed.
}

class from multicharts
public interface ITrade
{
ITradeOrder EntryOrder { get; }
ITradeOrder ExitOrder { get; }
bool IsLong { get; }
bool IsOpen { get; }
}

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: MultiCharts .NET Programming Guide

Postby Henry MultiСharts » 19 Apr 2013

Thanks for the guide. quick question about the Itrade Interface. In the guide pg 46 we have the double profit member, and commission which I cannot find in the code. see below for the Itrade from the code. pls clarify

public interface ITrade
{
double CommissionValue { get; } – commission of the trade
ITradeOrder EntryOrder { get; } – the order, that opened the trade - entry
ITradeOrder ExitOrder { get; }– the order, that closed the trade - exit
bool IsLong { get; } – Means, that the entry was Buy (true) or SellShort (false)
bool IsOpen { get; } – Means, that the entry was not closed yet
double Profit { get; } – OpenPL, if the trade is opend or TradeProfit – if closed.
}

class from multicharts
public interface ITrade
{
ITradeOrder EntryOrder { get; }
ITradeOrder ExitOrder { get; }
bool IsLong { get; }
bool IsOpen { get; }
}
You can check the commission for a closed trade in a position:
Image
Attachments
2013-04-19_153135.png
(7.9 KiB) Downloaded 3756 times

SysInv
Posts: 28
Joined: 25 Nov 2012
Has thanked: 1 time
Been thanked: 1 time

Re: MultiCharts .NET Programming Guide

Postby SysInv » 02 May 2013

Much appreciated, great job. Do you have some kind of mailing list or rss or similar to get notified about .net updates and things like this programming guide?

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: MultiCharts .NET Programming Guide

Postby Henry MultiСharts » 03 May 2013

Please follow us on Twitter, Facebook, LinkedIn, and our Traders’ Blog to get the latest updates.

Jobauma
Posts: 113
Joined: 16 Apr 2013
Has thanked: 25 times
Been thanked: 6 times

Re: MultiCharts .NET Programming Guide

Postby Jobauma » 14 May 2013

Thanks. I've learned so much already. This is great!

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: MultiCharts .NET Programming Guide

Postby JoshM » 17 Sep 2013

On page 28, the manual says:
All of the drawings are created by calling the Create () method.
The code example, however, uses CalcBar():

Code: Select all

protected override void CalcBar()
{
if (Bars.CurrentBar == 1)
{
ChartPoint top = new ChartPoint(Bars.TimeValue, Bars.HighValue);
ChartPoint bottom = new ChartPoint(Bars.TimeValue, Bars.LowValue);

DrwTrendLine.Create(bottom, top);
DrwArrow.Create(bottom, false);

ITextObject textObj = DrwText.Create(top, "1");
textObj.VStyle = ETextStyleV.Above;
}
}
(And using CalcBar() works while using Create() gives an runtime error).

Then a cryptic statement is made on page 28 that implies (as I read it) that the Create() method can access the CalcBar() drawings by 'forming a corresponding type of drawing' (implicit copying?):
The Create() method will form a corresponding type of drawing and bring back the reference to the interface which can be used to manipulate the object: it can be moved and its properties and styles can be changed.
I don't follow this; who can explain it? :) Since Create() is called before CalcBar() in the construction of an indicator, I'm not sure how this would be possible.

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: MultiCharts .NET Programming Guide

Postby JoshM » 19 Sep 2013

The BarsBack code example (4.5.3, page 36; manual version 1.0) gives an error (reference not set to an instance of an object-exception): the instantiation of the VariableSeries is missing.

This works:

Code: Select all

namespace PowerLanguage.Indicator
{
public class BarsBackTest : IndicatorObject
{
private VariableSeries<Double> plotValue;
private IPlotObject plot1;

public BarsBackTest(object _ctx):base(_ctx){}

protected override void Create()
{
plot1 = AddPlot(new PlotAttributes("Test"));
plotValue = new VariableSeries<Double>(this); // This line is missing from the example
}

protected override void CalcBar()
{
plotValue.Value = Bars.Close[10] - Bars.CloseValue;
plot1.Set(0, plotValue.Value);
}
}
}
(I've already fixed it in the Wiki)



----
Edit: In the DataLoader example, starting on page 73, there is a small error in step 9. Prior to adding:

Code: Select all

private List<Bar> m_EURJPY = new List<Bar>();
private List<Bar> m_EURAUD = new List<Bar>();
A reference to the System.Collections.Generic namespace must be made:

Code: Select all

using System.Collections.Generic;
(I've already updated the Wiki)

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: MultiCharts .NET Programming Guide

Postby JoshM » 19 Sep 2013

If I follow the DataLoader example in the manual, I get an error message (on MultiCharts .NET64 Version 8.7 Release (Build 7636)). I've double-checked it, and it seems I've made no mistake compared to the example.

Would someone be willing to take a look at my code to see where I go wrong? Or, if someone has coded that example in the manual already, would you be willing to share it?

Here's what I have:

Code: Select all

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using System.Collections.Generic;

namespace PowerLanguage.Indicator
{
public class DataLoaderExample : IndicatorObject
{
private IPlotObject spreadPlot;
private List<Bar> m_EURJPY = new List<Bar>();
private List<Bar> m_EURAUD = new List<Bar>();

public DataLoaderExample(object _ctx):base(_ctx){}

protected override void Create()
{
spreadPlot = AddPlot(new PlotAttributes("Spread", EPlotShapes.Line, Color.Red));
}

protected override void StartCalc()
{
InstrumentDataRequest Request = Bars.Request;
Request.Subscribe2RT = true;

DataRequest myDataRequest = new DataRequest();
myDataRequest.RequestType = DataRequestType.BarsBack;
myDataRequest.Count = Bars.FullSymbolData.Count;
Request.Range = myDataRequest;

Request.QuoteField = RequestQuoteField.Ask;
Request.Symbol = "EUR/JPY";
Request.Exchange = "FOREX";
Request.DataFeed = "LMAX";

DataLoader.BeginLoadData(Request, OnData, null);

Request.QuoteField = RequestQuoteField.Bid;
Request.Symbol = "EUR/AUD";
Request.Exchange = "FOREX";
Request.DataFeed = "LMAX";

DataLoader.BeginLoadData(Request, OnData, null);
}

protected override void CalcBar()
{
if (Bars.Status == EBarState.Close)
{
int index = Math.Min(Bars.CurrentBar, Math.Min(m_EURAUD.Count - 1, m_EURJPY.Count - 1));
if (index > 0)
{
spreadPlot.Set(Math.Abs(m_EURAUD[index].Close - m_EURJPY[index].Close));
}
}
}

public void OnData(IDataLoaderResult Result)
{
if (Result.Request.Symbol == "EUR/JPY")
{
ProcessData(m_EURJPY, Result);
}
if (Result.Request.Symbol == "EUR/AUD")
{
ProcessData(m_EURAUD, Result);
}
}

private void ProcessData(List<Bar> Container, IDataLoaderResult Result)
{
switch (Result.Event)
{
case DataLoadedEvent.History:
Container.AddRange(Result.Data);
break;
case DataLoadedEvent.RTNewBar:
if(Result.RTData.HasValue)
Container.Add(Result.RTData.Value);
break;
default:
break;
}
}
}
}
Image
Attachments
scr.19-09-2013 20.24.05.png
(26.48 KiB) Downloaded 2741 times

User avatar
Dave Masalov
Posts: 1712
Joined: 16 Apr 2010
Has thanked: 51 times
Been thanked: 489 times

Re: MultiCharts .NET Programming Guide

Postby Dave Masalov » 17 Oct 2013

If I follow the DataLoader example in the manual, I get an error message (on MultiCharts .NET64 Version 8.7 Release (Build 7636)). I've double-checked it, and it seems I've made no mistake compared to the example.

Would someone be willing to take a look at my code to see where I go wrong? Or, if someone has coded that example in the manual already, would you be willing to share it?
Hello JoshM,

The example in manual is incomplete. It will be changed shortly. Thank you for reporting.

Please try to use the following code:

Code: Select all

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using System.Collections.Generic;

namespace PowerLanguage.Indicator
{
public class DataLoaderExample : IndicatorObject
{
private IPlotObject spreadPlot;
private List<Bar> m_EURJPY = new List<Bar>();
private List<Bar> m_EURAUD = new List<Bar>();

public DataLoaderExample(object _ctx):base(_ctx){}

protected override void Create()
{
spreadPlot = AddPlot(new PlotAttributes("Spread", EPlotShapes.Line, Color.Red));
}

protected override void StartCalc()
{
InstrumentDataRequest Request = Bars.Request;
Request.Subscribe2RT = true;

DataRequest myDataRequest = new DataRequest();
myDataRequest.RequestType = DataRequestType.BarsBack;
myDataRequest.Count = Bars.FullSymbolData.Count;
myDataRequest.To = DateTime.Now;
Request.Range = myDataRequest;

Request.QuoteField = RequestQuoteField.Ask;
Request.Symbol = "EUR/JPY";
Request.Exchange = "FOREX";
Request.DataFeed = "LMAX";
Request.Category = ESymbolCategory.Forex;

DataLoader.BeginLoadData(Request, OnData, null);

Request.QuoteField = RequestQuoteField.Bid;
Request.Symbol = "EUR/AUD";
Request.Exchange = "FOREX";
Request.DataFeed = "LMAX";

DataLoader.BeginLoadData(Request, OnData, null);
}

protected override void CalcBar()
{
if (Bars.Status == EBarState.Close)
{
int index = Math.Min(Bars.CurrentBar, Math.Min(m_EURAUD.Count - 1, m_EURJPY.Count - 1));
if (index > 0)
{
spreadPlot.Set(Math.Abs(m_EURAUD[index].Close - m_EURJPY[index].Close));
}
}
}

public void OnData(IDataLoaderResult Result)
{
if (Result.Request.Symbol == "EUR/JPY")
{
ProcessData(m_EURJPY, Result);
}
if (Result.Request.Symbol == "EUR/AUD")
{
ProcessData(m_EURAUD, Result);
}
}

private void ProcessData(List<Bar> Container, IDataLoaderResult Result)
{
switch (Result.Event)
{
case DataLoadedEvent.History:
Container.AddRange(Result.Data);
break;
case DataLoadedEvent.RTNewBar:
if(Result.RTData.HasValue)
Container.Add(Result.RTData.Value);
break;
default:
break;
}
}
}
}

User avatar
Dave Masalov
Posts: 1712
Joined: 16 Apr 2010
Has thanked: 51 times
Been thanked: 489 times

Re: MultiCharts .NET Programming Guide

Postby Dave Masalov » 17 Oct 2013

The BarsBack code example (4.5.3, page 36; manual version 1.0) gives an error (reference not set to an instance of an object-exception): the instantiation of the VariableSeries is missing.
Thank you for reporting.

User avatar
Dave Masalov
Posts: 1712
Joined: 16 Apr 2010
Has thanked: 51 times
Been thanked: 489 times

Re: MultiCharts .NET Programming Guide

Postby Dave Masalov » 24 Oct 2013

On page 28, the manual says:
All of the drawings are created by calling the Create () method.
The code example, however, uses CalcBar():

Code: Select all

protected override void CalcBar()
{
if (Bars.CurrentBar == 1)
{
ChartPoint top = new ChartPoint(Bars.TimeValue, Bars.HighValue);
ChartPoint bottom = new ChartPoint(Bars.TimeValue, Bars.LowValue);

DrwTrendLine.Create(bottom, top);
DrwArrow.Create(bottom, false);

ITextObject textObj = DrwText.Create(top, "1");
textObj.VStyle = ETextStyleV.Above;
}
}
(And using CalcBar() works while using Create() gives an runtime error).

Then a cryptic statement is made on page 28 that implies (as I read it) that the Create() method can access the CalcBar() drawings by 'forming a corresponding type of drawing' (implicit copying?):
The Create() method will form a corresponding type of drawing and bring back the reference to the interface which can be used to manipulate the object: it can be moved and its properties and styles can be changed.
I don't follow this; who can explain it? :) Since Create() is called before CalcBar() in the construction of an indicator, I'm not sure how this would be possible.
Hello JoshM,

I am afraid you are confusing the CStudyAbstract.Create() method with the following methods: IArrowContainer.Create(), ITextContainer.Create(), ITrendLineContainer.Create().

Programming guide describes the latter three that create corresponding drawings.


Return to “MultiCharts .NET”