TWM Wiki

Description

Indicators

TWM comes preset with default indicators. Each indicator source code is open for review within the Custom project. Below you can find overall description of Indicator API.




Setting Name & Guid

Each indicator should be assigned a unique GUID. Each indicator class name must match indicator file name exactly. To create a GUID in Visual Studio proceed to Tools -> Create Guid -> New Guid and paste the string into new Guid("GUID string") method. GUID and name should be assigned inside the SetDefaults part of OnStaeChanged override.


public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
Name = IndicatorName;
Guid = new Guid(IndicatorGuid);
}
}


Input

In the below example we can see that the Input[0] is used. This indicates that anyhting that the user assigns as the input will be passed into this series. This is true for UI as well as for bringing input from other indicators and/or strategies. By default the Close prices are passed, however this can be adjusted if the indicator is designed to do so.

public override void OnBarUpdate()
{
_priorSum = _sum;
_sum = _priorSum + Input[0] - (CurrentBar-1 >= Period ? Input[Period] : 0); MA[0] = _sum / (CurrentBar-1 < Period ? CurrentBar : Period);
}

Below we can see the EMA indicator gets initialized with a High and Low series passed as input. If we do not pass anything as the first parameter, the Close series will be passed by default under the hood.

private Indicator _maFast;private Indicator _maSlow;
private void AddIndicators()
{
_maFast = EMA(High, PeriodFast); _maSlow = EMA(Low, PeriodSlow);
}

Initialization from Strategy

The indicator will be plotted on chart by default if it is initialized without ScriptOptions parameter passed. User has an option to hide the indicator from chart or hide the indicator panel from chart by assigning appropriate ShowPlots and ShowPanes booleans in the ScriptOptions object.

private Indicator _maFast;
private void AddIndicators()
{
var options = new ScriptOptions { ShowPlots = true, ShowPanes = false};
_maFast = EMA(High, PeriodFast, options);
}

Pane & Plot & Series

The indicator has to be created in a certain order.

  1. Create Plot
  2. Create a custom pane if required and add plot to pane or to price pane
  3. Create Series
  4. Assign series data to the created plot
[Browsable(false)][XmlIgnore]
public Series<double> MA { get; set; }

private Plot _plot;

public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
MAThickness = 1; MAColor = Colors.Green; Period = 14;

//1 - create plot
_plot = new Plot()
{
Thickness = MAThickness, Color = MAColor
};

//2 - adding plot to existing price pane does not require extra pane creation, just add.
AddPanePlot(_plot);

//alternatively you can add as many panes as you want and add plots to them
//you can have multiple panes within one indicator instance
var secondPane = AddPane();
AddPanePlot(secondPane, _plot);

}
else if (State == State.Configured)
{
//3 - create an empty series and use AddSeries to enable it
MA = new Series<double>();
AddSeries(MA);

//4 - asign series data to plot data source
_plot.DataSource = MA;
}
}

Plot Parameters

The plot can have some parameters that are possible to be assigned.

{
Name = "This name will come up in the data box";
Color = Colors.Blue; LineType = PlotLineType.Solid; //can also set Dashed
Thickness = 2;
ChartType = PlotChartType.Linear; //can also set Bars for histrogram style
}

If you plan to interact with plot colors inside the script, for instance by conditionally updating their color you need to make some extra settings and pass the PlotColors context.

public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
_plot_.PlotColors = new ColorMap(DataCalcContext);
}
}

public override void OnBarUpdate()
{
if (Diff[0] > 0)
{
_diff.PlotColors[0] = Brushes.Green;
}
if (Diff[0] < 0)
{
_diff.PlotColors[0] = Brushes.Red;
}
}

Complex Calculations

You can also make your calculations within the script and pass the calculated values into another indicator. This is quite common for averaging purposes. For instance calculating something inside the OnBarUpdate and passing the calculated series into an SMA.

Below is an illustrated example with SMA indicator initialized on the main price pane and two extra indicators engaged on an extra pane. The additional indicators are MIN and MAX indicators using the calculated SMA value from within a single instance of the same indicator.

Image


[Browsable(false)]
[XmlIgnore]
public Series<double> MA { get; set; }
[Browsable(false)]

[XmlIgnore]
public Series<double> MAMin { get; set; }
[Browsable(false)]

[XmlIgnore]
public Series<double> MAMax { get; set; }

private Plot _plot;
private Plot _plotMaMin;
private Plot _plotMaMax;

// Additional indicators to be used with calculations
private Indicator _maMax;
private Indicator _maMin;

public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
Name = IndicatorName;
Version = IndicatorVersion;

var MAThickness = 1;
var MAColor = Colors.Green;
Period = 14;

_plot = new Plot() { Thickness = MAThickness, Color = MAColor };
AddPanePlot(_plot);

// Creating two extra plots for MIN and MAX
_plotMaMin = new Plot() { Thickness = MAThickness, Color = Colors.Blue };
_plotMaMax = new Plot() { Thickness = MAThickness, Color = Colors.Orange };

// Adding both to same new pane
var maMixMinPane = AddPane();
AddPanePlot(maMixMinPane, _plotMaMin);
AddPanePlot(maMixMinPane, _plotMaMax);
}
else if (State == State.Configured)
{
MA = new Series<double>();
AddSeries(MA);
_plot.DataSource = MA;

MAMin = new Series<double>();
AddSeries(MAMin);
_plotMaMin.DataSource = MAMin;

MAMax = new Series<double>();
AddSeries(MAMax);
_plotMaMax.DataSource = MAMax;

// Assigning MA series as the input of the indicators
_maMax = Max(MA, Period);
_maMin = Min(MA, Period);
}
}

public override void OnBarUpdate()
{
_priorSum = _sum;
_sum = _priorSum + Input[0] - (CurrentBar - 1 >= Period ? Input[Period] : 0);
MA[0] = _sum / (CurrentBar - 1 < Period ? CurrentBar : Period);

// Getting the values
MAMax[0] = _maMax[0];
MAMin[0] = _maMin[0];
}

Although the exact same output can be achieved using the next example, it is highly unrecommended to use do this because this boosts up CPU usage significantly especially of complex calculations.

public override void OnBarUpdate()
{
_priorSum = _sum;
_sum = _priorSum + Input[0] - (CurrentBar - 1 >= Period ? Input[Period] : 0);

MA[0] = _sum / (CurrentBar - 1 < Period ? CurrentBar : Period);

// NOT RECOMMENDED!!!
MAMax[0] = Max(MA, Period)[0];
MAMin[0] = Min(MA, Period)[0];
}



Important

  1. Indicator class name MUST match file name.
  2. Unique GUID should be generated for each IndicatorGuid parameter.
  3. If you create an indicator in an extended namespace, it will create a folder inside the indicator UI inside TWM. If you do so, you MUST create a physical folder on the file structure as well.


Common Mistakes

The most common mistake users will make is get index out of range exception. When OnBarUpdate method executes on the first bar you cannot address a previous bar yet because it does not exist. If your logic requires that, in that case you need to skip this bar. See example below. Please note that in TWM first bar on the left hand side of the chart is CurrentBar = 1.


public override void OnBarUpdate()
{
if (CurrentBar < 2)
return;

//logic that requires previous bar
if (High[0] > High[1]
{

}
}

Another common mistake would be placing cs files into the project by manually copying them into the file structure. If you do so make sure the information about the file exists inside the csproj file. Usually you would use Add Existing File command inside VS to add it properly so it imports correctly into the project structure. TWM uses the project file XML information and therefore if the newly added file meta data does not exist inside the csproj file there is no way for it to be seen within TWM.


This website uses cookies to enhance your browsing experience. By continuing to use our website, you agree to our Privacy Policy

Necessary cookies help make a website usable by enabling basic functions such as page navigation and access to protected areas of the site.

  • Necessary cookies

    .AspNet.Consent

    Indicates whether the user has consented to the use of necessary cookies.

    Maximum storage duration: 1 Year | Type:Necessary cookies
    .AspNetCore.Antiforgery

    Used to prevent CSRF attacks and protect user data.

    Maximum storage duration: Session | Type: Necessary cookies
    .AspNetCore.Cookies

    Used to manage authentication information and the user's session.

    Maximum storage duration: 1 Year | Type: Necessary cookies
    .AspNetCore.Culture

    Used to store user's language preferences.

    Maximum storage duration: 1 Year | Type: Necessary cookies
    __Secure-OSID

    Security cookie set by Google to authenticate users and prevent fraudulent use of login credentials.


    Maximum storage duration: 6 Months | Type: Necessary cookies
    __Host-3PLSID

    Ensures you stay connected to your Google accounts across various services.

    Maximum storage duration: 2 Years | Type: Necessary cookies
    AEC

    Used to verify your Google account and ensure that requests in sessions come from you.

    Maximum storage duration: 6 Months | Type: Necessary cookies
    HSID

    Security cookie used by Google to authenticate users and prevent fraudulent use of login credentials, protecting user data.

    Maximum storage duration: 2 Years | Type: Necessary cookies
    SEARCH_SAMESITE

    This cookie prevents the browser from sending the cookie along with cross-site requests, helping to mitigate the risk of cross-origin information leakage.

    Maximum storage duration: 6 Months | Type: Necessary cookies
    SID

    Important for Google's security and to ensure that Google can authenticate the account and block fraudulent access attempts.

    Maximum storage duration: 2 Years | Type: Necessary cookies
    SIDCC

    Security cookie to protect user data from unauthorized access.

    Maximum storage duration: 1 Year | Type: Necessary cookies
    __Host-1PLSID, __Host-3PLSID

    Crucial cookies to ensure that you remain securely logged into your Google accounts while accessing various Google services.

    Maximum storage duration: 2 Years | Type: Necessary cookies

Functional cookies allow the website to provide enhanced functionality and personalization. They may be set by the website owner or by third parties whose services have been added to the pages.

  • Functional Cookies

    LSOLH

    Used by Google to store session information and enhance the user's experience on Google services.


    Maximum storage duration: Session | Type: Functional Cookies
    COMPASS

    Used by Google to improve user navigation by remembering preferences and information, such as preferred language.

    Maximum storage duration: 6 Months | Type: Functional Cookies
    ACCOUNT_CHOOSER

    Remembers which accounts have been used to log into Google services on the device.

    Maximum storage duration: 1 Year | Type: Functional Cookies
    APISID

    Used by Google to store user preferences and information when viewing pages with Google maps.

    Maximum storage duration: 2 Years | Type: Functional Cookies
    LSID

    Used by Google to store user preferences while viewing pages that incorporate Google services.

    Maximum storage duration: 2 Years | Type: Functional Cookies
    NID

    Used by Google to remember user preferences, such as preferred language, to provide a more personalized experience.

    Maximum storage duration: 6 Months | Type: Functional Cookies
    SAPISID

    Used by Google to collect information about visitors for videos hosted on YouTube or maps integrated with Google Maps.

    Maximum storage duration: 2 Years | Type: Functional Cookies
    __Host-GAPS

    Used by Google to store user preferences and information when pages containing maps or Google services are viewed.

    Maximum storage duration: 2 Years | Type: Functional Cookies

Statistical cookies help website owners understand how visitors interact with the site by collecting and transmitting information anonymously.

  • Statistical Cookies

    CLID

    Unique identifier used to track user interactions and maintain unique sessions.


    Maximum storage duration: 1 Year | Type: Statistical Cookies
    MR

    Microsoft cookie that collects data on user interactions to improve services.

    Maximum storage duration: 7 days | Type: Statistical Cookies
    SM

    Used by the Microsoft Clarity analytics suite to maintain the user's session.

    Maximum storage duration: Session | Type: Statistical Cookies

Marketing cookies are used to track visitors on websites. The intent is to display relevant and engaging ads for the individual user.

  • Marketing Cookies

    AID

    Used by Google to link your activity across devices if you have logged in with the same Google account.


    Maximum storage duration: 1 Year | Type: Marketing Cookies
    ANONCHK

    Used by Microsoft Advertising to check the anonymity of data sent by tracking cookies.

    Maximum storage duration: 10 minutes | Type: Marketing Cookies
    MUID

    Microsoft cookie used to track user interactions across Microsoft domains.

    Maximum storage duration: 13 Months | Type: Marketing Cookies
    __Secure-3PSID, __Secure-3PAPISID, __Secure-3PSIDTS, __Secure-3PSIDCC

    Google cookies designed to build a profile of your preferences and show you relevant ads on other sites, protecting the Google account.

    Maximum storage duration: 2 Years | Type: Marketing Cookies
    ADS_VISITOR_ID

    Used by Google to identify and track visitors across various websites to display personalized advertising.

    Maximum storage duration: 2 Years | Type: Marketing Cookies
    OTZ

    Used by Google to personalize ads on Google properties, like Google Search.

    Maximum storage duration: 1 Month | Type: Marketing Cookies
    __Secure-1PAPISID, __Secure-1PSID

    Used by Google to deliver more relevant ads and protect the security of your preferences and Google account information.

    Maximum storage duration: 2 Years | Type: Marketing Cookies

Cookies are small text files that can be used by websites to make the user's experience more efficient.

The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies, we need your permission. This means that cookies classified as necessary are processed under Article 6(1)(f) of the GDPR. All other cookies, namely those belonging to the categories of preferences and marketing, are processed under Article 6(1)(a) of the GDPR.

This site uses different types of cookies. Some cookies are placed by third-party services that appear on our pages.

You can change or revoke your consent at any time from the Cookie Statement on our website.

Learn more about who we are, how you can contact us, and how we process personal data in our Privacy Policy.

Specify your consent ID and the date you contacted us regarding your consent.