TWM Wiki

Description

Strategies – Order Types, Events & Position Handling

Initialization

Each strategy has to be created with a unique GUID. Inside Visual Studio you can go to Tools -> Create GUID to generate a unique GUID for your strategy.

private const string SystemVersion = " V1.0";
private const string StrategyName = "MA Crossover";
private const string StrategyGuid = "C8BFB4D3-2C74-469F-8A25-397BFE3DD574";

public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
Name = StrategyName + SystemVersion;
Guid = new Guid(StrategyGuid);
Version = SystemVersion;
}
}

Orders

To analyze potential fills during historical execution for stop-market, limit, orders TWM uses an internal BeforeBarUpdate event. The OnBarUpdate event occurs after the BeforeBarUpdate for the same bar index.

OrderAction.Buy - will open a long position, should be used on initial position opening and scaling in

OrderAction.Sell - will close a long position, should be used for closing the position or scaling out

OrderAction.SellShort - will open a short position, should be used on initial position opening and scaling in

OrderAction.BuyToCover - will close a short position, should be used for closing the position or scaling out

For live market OrderAction.Buy and OrderAction.BuyToCover will always buy and OrderAction.SellShort and OrderAction.BuyToCover will always sell.

Market Orders

Submitted market orders will get filled immidiatly. During historical execution TWM will use the next bar open value to fill the order.

private void PlaceMarketEntryOrder(bool isLong)
{
if (isLong)
{
_entryOrder = SubmitOrder(0, OrderAction.Buy, OrderType.Market, PosSize, 0, 0,0, "", EnterLongName);
}
if (!isLong)
{
_entryOrder = SubmitOrder(0, OrderAction.SellShort, OrderType.Market, PosSize, 0, 0,0, "", EnterShortName);
}
}

Limit Orders

For limit orders the following is true during historical execution.

  1. If there is NO position and order action is Buy and low of the upcoming bar is equal or below the set price OR order action is SellShort and high of the upcoming bar is equal or higher to the set limit price you will get a fill with the set limit price, your order state will be marked as filled, a new position will be created and a OnOrderUpdate event will occur. In case if there was a gap you will get a fill using the rule at price or better which will use the bar open.
  2. In case stop and profit orders have been set during the OnOrderUpdate the StrategyBase class will perform a check for stop and limit orders fills within the same bar.
private void PlaceLimitEntryOrder(bool isLong, double price)
{
if (isLong)
{
_entryOrder = SubmitOrder(0, OrderAction.Buy, OrderType.Limit, PosSize,price, 0,0, "", EnterLongName);
}
if (!isLong)
{
_entryOrder = SubmitOrder(0, OrderAction.SellShort, OrderType.Limit, PosSize, price, 0,0, "", EnterShortName);
}
}
Image


PlaceLimitEntryOrder(false, Low[0] - TickSize*50);

The above example clearly demonstrates where the historical order short fill has been filled with bar open price although its limit order price has been set 50 ticks below the signal bar low.

Stop-Market Orders

To understand stop market orders we need to understand the concept of trigger price. Basicaly a stop market order will execute a market order when the market gets to a trigger price. It does not matter where the market is at the moment you place this order.

  1. If the market is above trigger price, market order will execute when the market goes below trigger price.
  2. If the market is below trigger price, market order will execute when the market goes above trigger price.
  3. If the market is equals trigger price, market order will executed immediately.

It does not matter which order action we are planning on taking. The chosen action will execute once the conditions are met.

private void EnterMarket()
{
if (_enterLong)
PlaceStopMarketEntryOrder(true, High[0] + TickSize * 3);

if (_enterShort)
PlaceStopMarketEntryOrder(false, Low[0] - TickSize * 3);
}

private void PlaceStopMarketEntryOrder(bool isLong, double price)
{
if (isLong)
_entryOrder = SubmitOrder(0, OrderAction.Buy, OrderType.StopMarket, PosSize, 0, 0, price, "", EnterLongName);

if (!isLong)
_entryOrder = SubmitOrder(0, OrderAction.SellShort, OrderType.StopMarket, PosSize, 0, 0, price, "", EnterShortName);
}

In the example we see stop market sell executing a few ticks below the signal bar low. If there would have been a gap here the open price of the gap bar would have been used. However this is only because the market was above the trigger price when the order was placed.

Image


The below example however, illustrates a completely different approach where we have deliberately set a stop market sell order way higher than then current market. In this case, when the market did reach the trigger price, a market order was executed and filled at trigger price historically. In real market please expect appropriate slippage in such cases. Trigger price does not guarantee price, it guarantees execution of a merket order if the trigger price is reached.

if (_enterShort) PlaceStopMarketEntryOrder(false, High[0] + TickSize*300);
Image


On a historical market stop market orders behave differently when a position is already open. In this case they will act like a stop loss. If the position is open and a stop market order is placed main posints to consider are:

  1. These points are TRUE only for the historical execution
  2. You cannot scale in using this type of order
  3. The order can be used for exiting the position only

Stop-Limit Orders

Stop limit order will place a limit order at limit price once the market has reached the trigger price. The limit order itself will work exactly as a standard limit order. Historical execution of stop limit orders is not currently supported. You can use stop limit orders only for live execution and placement on the exchange.

private void PlaceStopLimitOrder(bool isLong, double price, double triggerPrice)
{
if (isLong)
_entryOrder = SubmitOrder(0, OrderAction.Buy, OrderType.StopLimit, PosSize, price, 0, triggerPrice, "", EnterLongName);

if (!isLong)
_entryOrder = SubmitOrder(0, OrderAction.SellShort, OrderType.StopLimit, PosSize, price, 0, triggerPrice, "", EnterShortName);
}

Positions

You can check existing strategy positions using the LastPosition command or by looking through the Positions collection. Last position will return the last position in the Positions collection. If a position exists and a new trade is made, it will add onto the existing position. Each Position consists of Trades that are stored inside it. In order to consider a position closed, all trades contained within a Position object have to be closed. If you close more trades than a Positoin object stores crating an overfill, the scipt will open a new Position to the other side.

if (LastPosition.MarketPosition == MarketPosition.Flat) return;
if (LastPosition.MarketPosition == MarketPosition.Long) return;
if (LastPosition.MarketPosition == MarketPosition.Short) return;

Important

It is highly recomended to prefix your global variables with an underscore. TWM will NOT automatically reset such variables in on State.Configured. YOU NEED TO DO SO MANUALLY!!!!

If you forget to do this your collections will not get reset unless you manually reset them inState.Configured.

Failing to reset your collections and global variables will result in memory leaks during re-execution in optimization and re-enabling on chart and validator. You can also face very strange executions and results as your global calculations can take on from iteration to iteration whilst enabling the strategy.


Edge Cases

During historical execution, when a market order is submitted from within OnOrderUpdate event it will get filled with order.StopPrice value to simulate market order on stop re-entry. That is only the case if StopPrice has been filled. If you are trading on a secondary, extra added time series it has to match the primary one exactly. For isntance, if your main timeframe is 5min, your secondary timeframe where you are placing order also has to be 5min.

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
About cookies and consent

This website uses cookies and similar technologies to ensure its proper functioning and, with your consent, to measure usage, improve performance, and provide personalized content or advertisements. The legal basis for the use of necessary cookies is the legitimate interest of the data controller (Art. 6(1)(f) GDPR), while functional, statistical, and marketing cookies are used only upon your explicit consent (Art. 6(1)(a) GDPR).

Cookies are small text files stored on your device to make the website work efficiently and improve your experience. Some cookies are placed directly by us, while others come from third-party services integrated into our pages.

Cookie categories
  • Necessary cookies: enable core site functionality such as navigation, language selection, and access to secure areas. These cannot be disabled.
  • Functional cookies: allow the website to remember your preferences and settings for a better user experience.
  • Statistical cookies: collect anonymous data on site usage to help us understand and improve performance.
  • Marketing cookies: used to display personalized advertisements based on your browsing interests.
Storage and consent management

Your cookie preferences are stored locally in a cookie named consent, valid for 12 months, and pseudonymously on our systems using a technical identifier (UserUUID), which does not allow direct identification of the user. You may change or withdraw your consent at any time via the cookie settings button visible at the bottom left of the site or through the link in this section.

Third-party cookies

Some cookies are provided by third-party services (e.g., Google, Microsoft). These third parties act as independent controllers or processors under their own privacy policies.

Your rights

You can withdraw or modify your consent at any time, delete cookies through your browser settings, and exercise your rights under Articles 15–22 GDPR (access, rectification, deletion, limitation, opposition, portability) by contacting us via the details provided in the Privacy Policy.

This Cookie Policy is aligned with Regulation (EU) 2016/679 (GDPR) and the ePrivacy Directive.