How to Execute Strategy in .NET

From FxCodeBaseWiki
Jump to: navigation, search

Overview

The sample program is a console application executing strategy on live data. It uses Indicore Integration SDK and Order2Go. It prints live data on the screen and alerts user about appearing signals. If strategy is alowed to trade, the program would create trading orders.

What Do You Need for a Strategy?

In order to create a strategy instance you need a strategy profile, two alive tick streams ("bid" and "ask"), strategy parameters, and a callback function which would be called when a signal ("Buy" or "Sell") appears or trading order has to be created.

Classes Used by Application Executing a Strategy

These are the main classes used by application:

MainClasses.png

The main class Program is responsible for loading a list of indicators and strategies, getting an indicator’s profile, and filling parameters for a strategy. It creates an instance of the strategy (an object of StrategyInstance class) implemented as MyStrategyInstance. Strategy instance always uses two tick sources (“bid” and “ask”), so you need to implement IndicatorTickSource class (MyIndicatorTickSource class in the example). Some strategies may use time frames other than “tick”. It means you will need to implement IndicatorBarSource class (MyIndicatorBarSource class in the example). Classes IndicatorTickSource and IndicatorBarSource are subclasses of IndicatorSource. Strategy uses Host class for host application. Class MyHost implements Host in the example. It is used to execute commands or to get data which are not covered by the standard interface of the indicators or the strategies. Strategy instance needs a callback function for trading signals and executing orders sent from the strategy, that’s why you have to implement StrategyCallback class (MyStrategyCallback class in the example). Program will notify strategy instance when asynchronous operations requested by strategy are completed.
Let’s have a look at MyHost class:

HostClasses.png

When MyHost gets commands getTradingDayOffset, getTradingWeekOffset or getTradingProperty, it calls Order2Go class. For getHistory commands MyHost is using HistoryMgr class. For setTimer and killTimer commands MyHost is using TimersMgr class.
We already mentioned that strategy always uses two tick streams (“bid” and “ask”), and some strategies use bar streams (“hourly” candles, “weekly” candles, etc.) Look at the streams’ creation and usage on the class diagram:

StreamClasses.png

History manager can create either MyIndicatorTickSource or MyIndicatorBarSource (MyIndicatorBarSource uses helper class BarData). History Manager keeps information about streams created for the strategy instance via Ticket class.
Class Order2Go is used for getting trading property, trading day offset, trading week offset, and price history helper (the last is used for getting a candle for specific time). When MyHost gets command findTable, it returns TradingDataTable. Class MyTradingTable implements TradingDataTable and contains information about trading tables (“Accounts”, “Offers”, “Orders”, “Trades”, “Closed Trades”, “Summary”, “Messages”). Class MyTradingTable also uses MyTradingRowEnumerator (subclass of TradingDataTableEnumerator) and MyTradingRow (subclass of TradingDataTableRow).

TradingClasses.png

Step #1. Add Indicore Integration SDK and Order2Go to the Project

To find out how to add Indicore Integration SDK to your .NET project please read the Start Using Indicore Integration SDK in .NET article. To find out how to add Order2Go to your .NET project please read C Sharp (O2GO) article.

Step #2. Providing Helper .Lua Files for Standard Strategies

If you are going to use standard strategy, you will need to create strategies\standard\include structure in the target directory and copy files from strategies\standard\include folder there

Step #3. Initializing Indicore Integration SDK and Order2Go

Initialize Indicator Core, Order2Go, and create trade desk object '"`UNIQ--toggledisplay-00000000-QINU`"'

Step #4. Subscribe to Price History Events

Some strategies have getHistory requests (they may need history from time frame other than “tick”). Accomplishment of these requests takes time, so you would need to use asynchronous functions. Subscribe to events OnPriceHistoryCompleted and OnPriceHistoryFailed

'"`UNIQ--toggledisplay-00000001-QINU`"'

Step #5. Subscribe to Request Events

Strategies can be allowed to trade. Creating trading orders should be done asynchronously as well. Subscribe to events OnRequestCompleted and OnRequestFailed

'"`UNIQ--toggledisplay-00000002-QINU`"'

Step #6. Login to Trade Desk

Log in using your user ID, password, URL, and connection ("real" or "demo") '"`UNIQ--toggledisplay-00000003-QINU`"'

Step #7. Load a List of Indicators and a List of Strategies

To find out how to initialize core and load indicators please read the How to Load Indicators in .NET article. Do similar steps to load strategies.

Step #8. Get a Strategy Profile

First of all you have to find the profile of the strategy to be created. Usually, strategies are referred by their identifier. For example "MA_ADVISOR" for Sample Moving Average strategy. In fact, the identifier is just a file name of the strategy without the extension and used in the upper case.

The profile is used to:

  • Get human-friendly name and description of the strategy.
  • Get the list of the parameters.

To enumerate the profiles or find them, you must use an instance of the StrategiesCollection class. Let's find the Sample Moving Average (MA_ADVISOR) strategy.

'"`UNIQ--toggledisplay-00000004-QINU`"'

Step #9. Get an Instance of Startegy Parameters and Fill It with Values

The strategy profile can be used to get the set of the parameters of the strategy. You can fill this parameter set or just use the default values. In the last case you can just pass null instead of the parameter set for creating strategy instance. Let's set the FMA_N (number of periods for fast moving average) to 6, and SMA_N (number of periods for slow moving avarage) to 20. For the strategy MA_ADVISOR used in the example you would need to set parameter CANTRADE to “Yes”, and parameter ACCOUNT to account ID in case the strategy is allowed to trade.

'"`UNIQ--toggledisplay-00000005-QINU`"'

Step #10. Implement Host Class

This class is used to execute the commands or get the data which are not covered by the standard interface of the indicators or the strategies. '"`UNIQ--toggledisplay-00000006-QINU`"'

Step #11. Create an Object of the Host class, and Set it as a Host for Indicore Manager Object

'"`UNIQ--toggledisplay-00000007-QINU`"'

Step #12. Implement a StrategyCallback class

Strategy uses StrategyCallback for “Buy” and “Sell” signals (sending alerts) and for executing trading orders if trading is allowed. executeOrder and alert functions (alertEmail, alertMessage, alertSound ) are the heart of the application. '"`UNIQ--toggledisplay-00000008-QINU`"'

Step #13. Create an object of StrategyCallback

'"`UNIQ--toggledisplay-00000009-QINU`"'

Step #14. Implement IndicatorTickSource

Strategy always need two “tick” streams for “bid” and “ask” prices. '"`UNIQ--toggledisplay-0000000A-QINU`"'

Step #15. Implement IndicatorBarSource

Strategy always uses two tick streams, but strategy may also need “bar” stream. You need to implement IndicatorBarSource in case the strategy can use time frame other than “tick” '"`UNIQ--toggledisplay-0000000B-QINU`"'

Step #16. Get and Keep Price Streams

Class HistoryMgr is used to prepare price streams: “bid” and “ask” sources for the strategy, as well as streams for strategy’s getHistory requests. History manager keeps strategy instance with a list of price streams for this instance in a dictionary. Class Ticket is used to keep all information about price stream. History manager has function PrepareTicks to create “bid” and “ask” sources for strategy. First it gets historic prices. It this case application uses synchronous call because prices have to be filled in order to create strategy instance. There could be new ticks coming from the moment of the GetPriceHistory call to the moment of getting the result with 300 ticks. Function GetPendingEvents of the trading desk is used to get new ticks. Function MergeTicksHistWithTicksBuffer is used to merge historic and new ticks. History manager has function GetPriceHistoryAsync for getHistory request from strategy. One of the arguments is a cookie from the strategy to be used in notifyFinished. GetPriceHistoryAsync function creates an empty stream, and sends an asynchronous call to get historic prices. Application does not wait for prices to be filled. Instead it gets request ID for the history request (it would be used in event OnPriceHistoryCompleted). The empty stream is attached to the instance of a strategy together with supporting information (price history request ID, cookie for notifyFinished). The stream would be kept with a flag PriceHistoryCompleted as “false” until prices would be filled. Function ProcessPendingEvents checks pending events, and in case there were new prices (“new offer” events), new ticks are added for all completed streams (ticks are kept in a buffer for uncompleted streams). Function ProcessTick adds new tick for all corresponding tickets (the tick should be stored in the tick buffer in case stream is not filled yet). Function AddTick2Stream adds a tick to tick stream or bar stream. Function Attach2Instance attaches price stream to strategy instance to keep them together in a dictionary. '"`UNIQ--toggledisplay-0000000C-QINU`"'

Step #17. Prepare Tick Sources for the Strategy

Enable pending events for the trading desk (it will allow you to store and later extract coming ticks). It is important to do it before the call to get last 300 ticks. Ask HistoryMgr class to prepare ticks for you. You need the tick history up to “now” (use 0 as date “from” and date “to”, and “t1” as time frame). History manager would do the work of merging “historic” ticks and “new” ticks.

'"`UNIQ--toggledisplay-0000000D-QINU`"'

Step #18. Keep Information about Orders

Class Order2Go keeps information about the trading orders requested by the strategy. In the example below the information is kept in a dictionary where strategy instance is a key, and the list with information about corresponding orders is a value. A helper class OrderInfo is used to keep information about an order (request ID, strategy’s cookie, and time of request. Class Order2Go is also used by MyHost to get trading day offset, trading week offset, trading properties, and for price history helper. '"`UNIQ--toggledisplay-0000000E-QINU`"'

Step #19. Create Strategy Instance

Create a strategy instance, using two “tick” streams, strategy callback function, and parameters. '"`UNIQ--toggledisplay-0000000F-QINU`"'

Step #20. Attach "Bid" and "Ask" Streams to History Manager

History manager (HistoryMgr) keeps all streams for the strategy instance. “Bid” and “ask” tick streams are special, because they were created before the strategy instance was born. That’s that is why you have to attach them to strategy instance right after creating a strategy instance with those streams. '"`UNIQ--toggledisplay-00000010-QINU`"'

Step #21. Watch for New Prices

Get into the loop. Program will ask history manager to process pending events (it is done by function ProcessPendingEvents), and in case there are new prices, all price streams associated with the strategy instance would get new ticks (bars), and the strategy instance would be updated. '"`UNIQ--toggledisplay-00000011-QINU`"'

Step #22. Watch for Price History Events

Each time when event OnPriceHistoryCompleted happens, check the dictionary in history manager, find a stream for the price history request, fill it with the prices you got, add new ticks stored in the buffer for the stream (if any), mark stream as completed, and call notifyFinished for the strategy instance (function FxCore_OnPriceHistoryCompleted). Notify strategy instance in case OnPriceHistoryFailed happens as well (function FxCore_OnPriceHistoryFailed).

Step #23. Watch for Request Events

If the strategy is allowed to trade, notify strategy instance when events OnRequestCompleted or OnRequestFailed happen (functions FXCore_OnRequestCompleted and FXCore_OnRequestFailed). Check Order2Go dictionary, find information about the order for specific request, get a cookie for the strategy, and call notifyFinished for the strategy instance.

Sample Project

You can download sample project here: File:ExecuteStrategyNET.zip.
To run the program use these arguments: username, password, instrument (optional), and time frame (optional). The default instrument in "EUR/USD", and default time frame is "m1" (one minute).

This Article in Other Languages

Language: English  • español • français • русский • 中文 • 中文(繁體)‎