TWM Wiki

Description

Core

Custom Project

TWM allows users to write their own extendable modules using C# language.

In this section you will find tutorials and help on the main API. TWM is installed together with a Custom project file where the user can write code. You can use any IDE of your choice.

In our documentation, we will be demonstrating everyhting with the help of Visual Studio Community Edition, which is a free IDE that can be downloaded from here.


Your initial installation will place the TWMCustom project in:

C:\Users\<UserName>\Documents\Twm\bin\Custom

In order to start working with the custom project, locate this folder and open the project or solution file Twm.Custom.csproj or Twm.Custom.sln

You can compile the custom project from within the IDE or by running any compilation commands from within TWM. You can learn more about compiling and debuging here.


Debuging

To Debug your project using an external IDE, please read this section You may alternatively debug using the Debug window of TWM, found in the Admin panel under New -> Debug. Use the command below to print to Debug window.

Print("Debug your code using this command");

Parameters

All parameters should be prefixed with a [TwmProperty] tag. In case this is an Indicator parameter, it will be passed to TWM auto code generator upon compilation, and become accessible inside the strategy code. For a strategy parameter, it will become available inside theOptimizer.

Parameter defaults should be assigned inside the OnStateChanged event

[TwmProperty]
[Display(Name = "Period", GroupName = Parameters, Order = 2)]
public int Period { get; set; }

Execution

Whenever a strategy or indicator changes state, the OnStateChanged event takes place. You can retrieve the new state of the tool and work with it. Some global parameters (such as Name and Version) should be set here.

  1. SetDefaults - whenever a user opens the UI for indicators or strategies (e.g., the dialog box listing all indicators and strategies). Use this state to set the default values that appear when you enable them.
  2. Configured - this is a one time call when users enable the strategy/indicator. Called when user clicks enable or apply.
public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
Name = "Indicator Name";
Version = "1.0";

}
else if (State == State.Configured)
{
}
}

All historical and live execution of TWM strategies and indicators occurs in OnBarClose. Please use the method below to create your code logic inside these overrides. To adress current bar values, please use the zero index as below. Previous bar index would be 1 in this case, etc. Please note that if you address a bar that does not exist on the chart you will get an index out of range exception. For instance, if there are only 5 bars on the chart, and you try and look back at Close[6] you will get an exception.

public override void OnBarUpdate()
{
var close = Close[0];
var open = Open[0];
var high = High[0];
var low = Low[0];
var time = DateTime[0];
}

During live execution of TWM strategies and indicators you can also use OnTickUpdate to execute your logic on a tick-by-tick basis. Address the live candle values appropriately.

public override void OnTickUpdate(ICandle candle, ICandle tick)
{
var close = candle.C;
var high = candle.H;
var low = candle.L;
var open = candle.O;
var time = candle.t;

Print("LIVE CANDLE. Close: " + close + " High: " +high +
" Low: " + low + " Open: " + open + " Time: " + time);

}

OnOrderUpdate event will occur every time there is any change inside the strategy order. Use this to manage your orders during historical strategy execution.

public override void OnOrderUpdate(Order order)
{
Print("On order update: " + order.Name +
" Qnt: " + order.Quantity +
" Price: " + order.FillPrice+
" Guid: "+ order.Guid +
" State: "+ order.OrderState);

if (State == State.Historical)
ManageOrders(order);
}

OnExecutionUpdate will occur only when something occurs to the order during live exectuion i.e., on the connection provider side. The OnExecutionUpdate event executes only when we get a callback from the exchange, it will not execute during historical strategy execution. Please make sure you are using OnOrderUpdate during historical execution.

public override void OnExecutionUpdate(Order order)
{
if (State == State.RealTime)
ManageOrders(order);
}

Adding Data Series

It is possible to add additional data series to an indicator or strategy. The SymbolName string is optional, if omitted, the series uses the same instrument.

Symbol name must match exactly as listed in the instrument list., and you must also specify the type:SPOT or FUTURE. The available connection short names are BybitMainnet and/or BinanceMainnet. You can add as many data series as you like.

AddDataSeries(DataSeriesType.Hour, 1,"DOGEUSDT", "FUTURE","BybitMainnet");

To address data contained with the added data series please use the below syntax.

public override void OnBarUpdate()
{
Print("Close:" + Closes[1][0] + " Open: " + Opens[1][0] + " High: " + Highs[1][0] + " Low: "+ Lows[1][0] + " Time: " + DateTimes[1][0]);
}

If you would like to submit a LIVE order against an added data series, please use the selected bars in progress parameter available inside each order method. In the case below the order will be submitted to the first added extra series.

_entryOrder = SubmitOrder(1, OrderAction.Buy, OrderType.Limit, PosSize, price, 0,0, "", EnterLongName);

Comissions

Comissions are an extendable TWM module. There are several pre-configured setups available. The comissions are calculated at the end of each trade and we have a chance to interact with the trade data in order to make extra calculations. The returned comissions value is deducted from the total P&L of the trade. Below is an example of most popular % based comission calculation.

public override double GetCommission(Trade trade)
{
var entry = (trade.ExitQuantity * trade.EntryPrice)*Commission/100;
var exit = (trade.ExitQuantity * trade.ExitPrice)*Commission/100;


return entry + exit;
}

TWM is already prese

t with spot and futures comissions presets for taker and maker options.

Optimization Fitness

You can access and code your own optimization fitness coefficient. Please look for examples in the optimization fitness folder. The optimzer will always try and find the max Value parameter that you pass from here.

public class MaxProfitFactor : OptimizationFitness
{
private const string OptimizationFitnessName = "Max Profit Factor";

public override void OnCalculatePerformanceValue(StrategyBase strategy)
{
Value = strategy.SystemPerformance.Summary.GetValue(AnalyticalFeature.ProfitFactor);
}
}


Using OnRender to Draw Objects on Chart

Alhtough TWM does provide some standard API to draw objects that are later treated inside the TWM UI it is also possible to use a much faster method to plot any drawing objects on chart using the standard System.Windows.Media methods inside the OnRender override. Below you can find an example of a strategy code that simply collects data from bar high and low values that are later used to draw a connecting line. Please do note that using this method has one limitation. The objects that is drawn has to be on the chart completely. If an object goes off chart partly it will not be plot untill you scroll horizontally and the object becomes completely visible.


public class RenderStrategy : Strategy
{
#region Constants

private const string SystemVersion = " V1.0";
private const string StrategyName = "On Render Strategy";
private const string StrategyGuid = "F715FC72-66EB-4A30-9461-48562117BC9D";

#endregion

#region Values

#endregion

#region Init

public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
SetDefaults();
SetParameters();
}
else if (State == State.Configured)
{
ClearDebug();
}
}

private void SetDefaults()
{
IsAutoscale = true;
Name = StrategyName + SystemVersion;
Guid = new Guid(StrategyGuid);
Version = SystemVersion;

}

private void SetParameters()
{

}

#endregion

private class Data
{
public double Price { get; set; }
public int BarIndex { get; set; }
}

private List<Data> _highs = new List<Data>();
private List<Data> _lows = new List<Data>();

public override void OnBarUpdate()
{
_highs.Add(new Data()
{
Price = High[0],
BarIndex = CurrentBar
});

_lows.Add(new Data()
{
Price = Low[0],
BarIndex = CurrentBar
});
}

public override void OnRender(DrawingContext drawingContext)
{
var pen = new Pen(Brushes.Blue, 2);
pen.Freeze();

for (int i = Chart.VisibleCandlesRange.StartIndex; i <= Chart.VisibleCandlesRange.EndIndex; i++)
{
if (i - 1 < 0)
continue;

var startX = Chart.GetXByBarIndex(_highs[i - 1].BarIndex);
var startY = Chart.GetYByPrice(_highs[i - 1].Price);
var endX = Chart.GetXByBarIndex(_lows[i].BarIndex);
var endY = Chart.GetYByPrice(_lows[i].Price);

var point1 = new Point(startX, startY);
var point2 = new Point(endX, endY);

drawingContext.DrawLine(pen, point1, point2);
}
}
}


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.