Muilti Instrument Strategy
Hi,
Could you point me in the right direction for documentation or an example of how to create a multi instrument strategy (which trades on each instrument). Anything simple is fine, I'm proficient in c# just unsure of what the use within PTMC.
Great product by the way!
Thanks
Hi tmfdouglas.
Appreciate your interest in PTMC. Personally I am glad to see proficient C# coders around this project. I think in order to create Multi Instrument Strategy you have more than one option, and which one suits you well is a matter of your decision. First and obvious solution is to perform strategy workflow via Trading System List (TSL).
Basically focus is on GetSortedInstruments (), which would allow you to retrieve all available instrument from vendor. Having all of them just simply use instances to grab Historical data per each if you would need to perform further calculations. Also it is possible to put data in internal or custom (iCustom) indicators. Again it is all up to your logic.
Another option is to create custom panel (plug-in), where the implementation of IExternalComponent interface will grants you Populate() method and NETSDK.PlatformEngine property. Having all these you are good to proceed further to the steps written above in TSL. Please note, that while developing acustom panel (plug-in): pros of this is high and advance flexibility, cons, if you need user interface, you need to create it on your own with WinForms.
One more option is to run same logic as in TSL but to convert script into bat (create console version button in the tsl window). With this option you can develop strategy and push it to vps without running it locally.
Please refer to codebase for source codes. And if you need more info on those thing, please provide details such as how you wish strategy to be run (independently on each instrument or as one solid ecosystem with profound risk management). I will try to assist you with this as much as i am qualified.Best Regards!
Thanks for the detailed response.
Re. the TSL, if I add additional data series in there to one strategy (so not within the code but through the gui) should this execute trades on each instrument individually? Reason I ask is that I've tried this during backtesting but it only executes trades on the main instrument (using 3ma cross and macd sample strategies).
Thanks
Hi tmfdouglas!
This code is an example you need to perform an additional data operations in your strategy. Worth to highlight, that you need to subscribe on the additional instrument in the code and unsubscribe after strategy is closed (this is how you will recieve addition quotes for the compared instrument in the TSL). Also, please upload db with both instruments to perform backtesting in the Algostudio.
this example does trading on the next bar if fast and slow MA is crossed on both current and compared instruments, closing of previous position is there as well.
Regards
public class Additional_data_example : NETStrategy { public Additional_data_example() : base() { #region Initialization base.Password = "66b4a6416f59370e942d353f08a9ae36"; base.ProjectName = "Additional_data_example"; #endregion } [InputParameter("Compared Instrument",0, 141)] public Instrument inst; [InputParameter("MA type", 1, new object[] { "EMA", MAMode.EMA, "LWMA", MAMode.LWMA, "SMA", MAMode.SMA, "SMMA", MAMode.SMMA, })] public MAMode MA_type = MAMode.SMA; [InputParameter("Fast period", 2)] public int Length_fast = 8; [InputParameter("Slow period", 3)] public int Length_slow = 24; [InputParameter("Magic Number", 15, 0, 9999)] public int NumMagic = 99; //magic number private Indicator Current_slowMA, Current_fastMA, Compared_slowMA, Compared_fastMA; HistoricalData Hist; Position[] All_pos; public override void Init() { Instruments.Subscribe(inst, QuoteTypes.Quote); Current_slowMA = Indicators.iMA(CurrentData, Length_slow, MA_type); Current_fastMA = Indicators.iMA(CurrentData, Length_fast, MA_type); Hist = GetHistoricalData(new HistoricalDataRequest(inst, CurrentData.Period)); Compared_slowMA = Indicators.iMA(Hist, Length_slow, MA_type); Compared_fastMA = Indicators.iMA(Hist, Length_fast, MA_type); } public override void NextBar() { bool buy_on_current = Current_slowMA.GetValue(0, 1) < Current_fastMA.GetValue(0, 1) && Current_slowMA.GetValue(0, 2) > Current_fastMA.GetValue(0, 2); bool buy_on_compared = Compared_slowMA.GetValue(0, 1) < Compared_fastMA.GetValue(0, 1) && Compared_slowMA.GetValue(0, 2) > Compared_fastMA.GetValue(0, 2); bool sell_on_current = Current_slowMA.GetValue(0, 1) > Current_fastMA.GetValue(0, 1) && Current_slowMA.GetValue(0, 2) < Current_fastMA.GetValue(0, 2); bool sell_on_compared = Compared_slowMA.GetValue(0, 1) > Compared_fastMA.GetValue(0, 1) && Compared_slowMA.GetValue(0, 2) < Compared_fastMA.GetValue(0, 2); All_pos = Positions.GetPositions(); if (buy_on_current && buy_on_compared) Entry(Operation.Buy); else if (sell_on_current && sell_on_compared) Entry(Operation.Sell); } public void Entry(Operation side) { All_pos.Where(p => p.MagicNumber == NumMagic) .ToList() .ForEach(p => p.Close()); NewOrderRequest request = new NewOrderRequest() { Instrument = Instruments.Current, Account = Accounts.Current, Type = OrdersType.Market, MagicNumber = NumMagic, Side = side, Amount = 1, Price = side==Operation.Buy? Instruments.Current.LastQuote.Ask: Instruments.Current.LastQuote.Bid }; Orders.Send(request); } public override void Complete() { Instruments.Unsubscribe(inst, QuoteTypes.Quote); } }
Thanks for the detailed example, it helps explain the logic and workflow of the API a lot.
Using this as an example if I wanted to backtest with multiple instruments is there a quicker way than adding the "Additional Data" one by one? I.e. can I select groups of instruments like I can in some other windows (all forex pairs etc...).
Thanks again
Specifically in this example, it does not make sense to load a whole bunch of Forex instruments by sorting it InstrumentType.Forex from all instrument list available from vendor, cuz it may unnecessarily cut your PC resources. It is also possible to choose only one instrument from lookup 141. Remember that you also will need to maintain in your code the subscription and unsubscription as well as loading historical data per each instrument in order to use indicator properly. Considering this example you can just add up to 5 more by adding input params and changing internal logic and this should be more than enough. Hope this make sense for you
Regards
Thanks. Say that I wanted to backtest across a whole group of instruments, but the strategy would only ever run on one instrument is there a way to do this? It seems it can be done using the example by adding the code for the additional instruments and adding them one by one to the additional data series but can the backtester be invoked to run multiple backtests, one for each instrument? (for example across all forex pairs). If so can this be done in the TSL or does one instance of the strategy have to be created for each instrument? (in this case each forex pair)
Thanks