New approach for testing algorithmic trading strategies

fan27: is your aim to sell the product or to trade your own systems?

selling this type of product may not give you good returns. the client base is so small
 
fan27: is your aim to sell the product or to trade your own systems?

selling this type of product may not give you good returns. the client base is so small
Both. Finding profitable algorithmic trading strategies is not easy. Once found, managing those strategies performance and combining them in an uncorrelated portfolio of strategies is also challenging. What makes you say the market for a solution that helps to solve those problems is small?
 
I created a document (attached to post) describing the platform I am currently building (C# .NET Core) to improve the process of finding profitable algorithmic strategies as described in the thread Removing the Golden Handcuffs.

Feedback appreciated.



New Approach for Testing Algorithmic Trading Strategies


Overview
The Problem

Typical algorithmic trading research platforms incorporate the paradigm of writing some code and then execute a backtest.


If (close > 50sma and close < lowerBollingerBand) then

Buy stock xyz

End if


In the above example, most platforms have the ability to optimize the indicator parameters in one process which does add time savings. The problem with this approach is it requires the user to manually code the construction of each strategy. Some platforms have built in Machine Learning capabilities but they are not always intuitive for users.


The Solution

Imagine we could wrap data relationships in components that implement a common interface. Imagine those data relationships could be defined as static (i.e. close > 50sma) or dynamic (i.e. close ? 50sma) which would be defined for each point in time. Imagine we could then instruct the platform how to test the various combination of components we are interested in. Let’s walk through an actual example and see the associated code. The platform is written C# .NET Core.


Note: The example below is very simple and only for demonstration purposes. Performance of strategies found via the code below would not be viable for live trading.

Example
hfcr9UMQKt234wO99-Qs1aCGiE_-l4_6AYHL8sPU5aHG2rl5KTFsKej2JPyR2qNpQ2cwoTOaD1FRRrajUA-AcLusu_ZPISZG-lXpKvgITgEZh3vPOL5O20wOuw4GIE3DV9XCfccH


Figure 1: Strategy Components


In Figure 1 above, note the variable higherTfsma200. This strategy component contains the data relationship between the close and the 200 sma of the target time frame (15 minute). Also note the Operator.LessThan value. This means the data relationship is static with close < 200 sma. Next, note the higherTfciv1 component. This strategy component uses a ChangeInValue indicator which is wrapped in the ChangeInValueConfiguration class (more on how that works later). Also note the Operator.Dynamic value. This indicates that the actual relationship will be determined for each point in time for the 15 minute time series. Next, note the higherTfciv2 component. The only difference between this component and the previous component is it will determine the ChangeInValue for the current close and the previous close where higherTfciv1 only determines the ChangeInValue for the current close.

Now that we have our strategy components, we are going to strategically assembly them in a Dictionary of ComponentConfiguration arrays. Note the construction of ccs (three keys of 0, 1, 2) and the requireKeys variable (0, 2). Each combination requires an element from the array at key 0 and 2 of the dictionary. There will only be one component per key in any combination. This will result in the following combination of these components.


higherTfsma200, targetTfciv1

higherTfsma200, targetTfciv2

higherTfsma200, targetTfciv1, higherTfciv1

higherTfsma200, targetTfciv1, higherTfciv2

higherTfsma200, targetTfciv2, higherTfciv1

higherTfsma200, targetTfciv2, higherTfciv2


For each of the component combinations above, the platform will go through each point in time in the data series and construct a strategy based on the components. If any of the data relationships that are not defined as Operator.Dynamic and are not true for that point in time, the strategy is not tested. The platform keeps track of which strategies it tests so as not to duplicate work.


H16YHqgarI3K78ouLOz3DMeuTAzO2tb46mmqSHomE5VrWwyjXbfvbsbCGBMFJLlDeHCxVYhaWSnZ6OoC2_GBf_ZXZDfti6xhwU-TSJFI0XVKJOK9OMALI4uWiheqh7_S_C-pgDL4


Figure 2: Order Builders


In Figure 2 we define the orders used in the backtest for each strategy. An OrderBuilder constructor takes two interface parameters which are IOrderConfigurator and IOrderDataRetriever which is implemented by the StopForRangeConfiguration and LimitForRangeConfiguration classes. By using publicly available interfaces, the users of the platform can easily extend the platform. More on that later. These two OrderBuilders will result in stop and limit orders that are 5 time the ATR value away from the entry price of the trade.


onjk8YjfxF6j7YUw2HUiQYZXCnPGFgifY0qnqPtbBxu6P58Jti5FNC1IcBQy-TimycE7Gb_8NJchbnhY8bqyT1D0hMJKN8X8RZuOy9_tEzhd8LLjKEO78YVw4RV7jJF8bfeZHC0b


Figure 3: Strategy Filters


In Figure 3 we define three strategy filters to use. These filters will instruct the platform that we are only interested in strategies that have at least 20 trades, a minimum win rate of 60% and an average trade result of 3%. Strategy filters classes implement the IStrategyFilter interface so users of the platform can create their own strategy filters.




JSri3HNSRoe5QQxAm1n_n3aDiiapSc0XEcMwpcrc0_gjlrkbgOUq7MYXjmyF9vV1m1pkQ5ysUfyoi26hkbSjJCVff_xFVFFapJ7jKGYkC3pBo-9W0L6aUZ6wjUt3_yqAECJ1Ny4a


Figure 4: Analyze


In Figure 4, we instantiate the StrategyComponentCombination class and call its analyze method which will create strategies based on the targetSymbol data and test those strategies against that symbol and symbols in allSymbols. For now, we are only testing one symbol (ES). The limitTrades parameter indicates whether to take all signals or just one signal per symbol at a time (i.e. limitTrades = true means symbol XYZ would not have overlapping trades for a strategy). To save on memory, we have saveTrades and generateCode set to false because we do not need that information for strategies that do not need meet the filter criteria. The List<AnalysisInfo> collection will contain the definition and results of the strategies that passed the strategy filters.


bsCrSsbqmaHPOa7YbIMK4AhvhvV0aON0daFHkK-qedKxRroXF-mASKAgKM8WOEwGQPwX_viDpbS159Kxa1_D3cKTqSp3lfzZ7z_TzNXhpIl-51Hrby81EKFpROwcFXIsG0Dlcx9I


Figure 5: Analyze filtered strategies on out of sample data


In Figure 5, we backtest the strategies that passed the strategy filters on a new set of data. Here we have saveTrades and generateCode set to true as we will want to output this information.


WhBZbqkpx30yTxHAX5WaPzZ1PN3RdjcNXxEkgPWVZfKdfVb5OBGAD-EX_qolL7ayrmrfkfCq98cNoAzpn-UUh9aqQ6jf1g_NUPy9cQrTWPJER-U3FDw1vAa7XXrULH66iyViQnn0


Figure 6: Filter strategies test on out of sample data


In Figure 6, the strategies are explicitly filtered from the results of the out of sample backtest. The next step (not shown here) is to output the results for further analysis.




iFFJS80ccTsoKBJx7owRj6HTtf2KFeV87qBDNO5EWPp7Mx9GWnMqodkEFjMUD7FRVpkY78xJsTYq77IgzISBVCtm78wi-g-ekpbsmDegUKVyONikQu3VE4gJ-uAHLb5eHudKXsNs


Figure 7: Actual execution of the preceding code


Figure 7 shows that out of the strategy component combinations, 1054 total strategies were generated and tested. Of those, 49 strategies ran against the training data passed the strategy filters and 4 of those 49 strategies passed the strategy filters on the out of sample data. The results were written to disc. The total time to execute was 29 seconds.


oGtWAy_nfNewdLGONqOi8fKIQFPedst70cVx8JciC8CmqJqpK1ldqvfFLDJPYviInJkpEb0Vz0C1h1huqIIf-OwVN5ZE3H8kPWJFzvmCnXdWTPiIbXsjboaoB5LheacUiF8vz1No


Figure 8: Order Optimization Code


In Figure 8, we now want to test various order combinations with our filtered strategies. We add our OrderBuilder arrays to a Dictionary and use the same concept of the Dictionary and requireKeys variable to instruct the platform how to combine the OrderBuilders for each strategy. The code above will result in 99 unique OrderBuilder combinations which are then tested against the filtered strategies.


Rn9UcYDtZu-V8rLiaxS3qPWxv85_VGnSAt6yx1NOVzwlgjfPvGmTUSZlyOsPRm5KPTxxrKCmeygm4NLwbd9DEy9cwsRzcL4ULGXBZvflJYFgv-iAfCJrmfvVl7XTaxuMpKDwTnqb


Figure 9: Order Optimization Execution


Figure 9 shows the order optimization execution. 99 order combinations were tested for the filtered strategies on the complete data set (ES 2002 to 2012) in 19 seconds.

dgksBq4ZCoill9IAsyaiAtZfRgJ8FztaOsgEQ6e-C9-EctiE4gnr0MGB0tZnHMs8YJsf7vkrMZcjcAkjbETHexTL0ot8SSuS3gxhorRxjjn5vnQx59RT_efPSq0ur01SCRGPZzCv


Figure 10: Result output of the filtered strategies written to disc


FtDf5SY5FSUNladHhWw3Dn32uAwMwxJwZrJA5mL47xAkMDBJwlS0UXllV67a64yYT4-cOpla1E32U1xQHnKAENO7uR3XR1yNgXGIleyGAgqo7QDqedcI2tB0BcZRufZAuX0UEGAF


Figure 11: EdgeTestResults.csv content containing result metrics of the 4 filtered strategies


gbto24UUkEHu-feQYFEcThd8XMNhchB4lY6fVQmO40XKZQWOeAUQh4kfj2QY8euxQCOXkfEAxPq5wX_TcvXH1ZzIQERdEH5Du_bnPcn1Zl8rLxs87WRdrPColaOMH3x89i9SE3Ce


Figure 12: Code, results, trades and strategy definition data for one of the filtered strategies







hhwwYQO1EYV9zaSNLsHJlLw_AbtQ9Svyr9jEYx3jdbSJU_P2pf8XWy7L8Xfe-KCdmHV3CHRMTNDO37QCFDiDrb1JnVjcLfGmnb5uyMNZpYjt0Y3Q9S2K7HCDLG_zzCiJf4d5WlGe


Figure 13: C#/Pseudo Code of one of the filtered strategy


Figure 13 shows code generated for one of the filtered strategies. This code as it is now will not compile but eventually will be able to compile in the targeted platform.


rlhkWKFifHdfDoX1J_1mJR_Zu5spTPxTx_OgJSqC1gP7iF1UOGvVJ9NBgrL_f1UjJ9_AvFaDBmh9CiShEjf9lVj0WzqAWcY7Dn9ADIyFhsXh-AeiOmf3Xz5rtH_kbUoWHiVkcGtG


Figure 14: Contents of OrderCombos directory


aLWwokoK3NgQ46yMAC2yIKt2cOI_ly9ymtNMQjyp4uH4nmpQND8KQ4GgumwxbtJp2G6OyRVlYbQJxfuetofPhL8USpWzeko09dPzbaZtQhs5poEs1U5Iw0P34k2AHkO1xB1EJEdr


Figure 15: Contents of the directory containing the first filtered strategy and the output of all order combinations



E4x8ay4Sd843MRRh8FP1bprABuCAOc9pgIW1PqYeZ5gcX9ouzXdn4IehtrlG1E-cHOscNKJ9uUEWzLTLcekvAurLxhXU2lxTXKcF6qHzZnFpYsjnXx31HDoNw9204Xnjtm1MZjDe


Figure 16: Contents of OrderComboResults.csv containing results for all of the order combinations



Extending the Platform
bPlLtAmxPHmU2j5ZHsQHYyNzoa_zooqWUNUMw2rNZxNoiBWS1QbHV2ijYAMBs6MPcx1NUmciKrBg4iVSllV3PHbtWLM-QlXq6HN9nKZHo-mQCvwqbsfdhWe2Mo4FfiKEEpr3STpQ


Figure 16: Class implementing IDerivedDataConfigurator interface


Figure 16 shows how to wrap indicator calls and resulting data to make available by the platform via the IDerivedDataConfigurator interface. See Figure 1 for a demonstration of how the SmaConfiguration class is used in a strategy component. The GetDerivedData method calls into the external indicator code and the GetCode method gets the code required to make a call to the indicator. For now, this is C# code but will eventually be a more general purpose format that can be consumed by interpreter classes which can generate code for other platforms.


qDy-_2CJGi3pxLFvLfGbji-WAaULNSbzg0uslSrUd9miYht28FpV0ekCcjj2ckoBmNLZ1cTraooOwArtSYgFH3UnSqHZfWGMeejf3OJuLj1WyIIPuzqUT0GOUurxqKMsd0ePndLk


Figure 17: Class implementing IOrderConfigurator and IOrderDataRetriever interfaces


Figure 17 shows how users can create their own order logic via classes implementing the IOrderConfigurator and IOrderDataRetriever interfaces. See Figure 2 for an example of how the LimitForRangeConfiguration class is used to create and OrderBuilder.


L2eVuBVJqP-ewDvE_ppGLg8hSMeVB5FsDyrNJY0LEyucpAuQoEBvKHjpEub0cxsQfh7ohc5plPeBjd16C54yn44elrTNXRIkXMrb-HfAAb3EZW6ZegV15mupxGkieTCqwyzUu1Qt


Figure 17: Class implementing the IStrategyFilter interface


Figure 17 shows the MinimumTradeCountFilter class implementing the IStrategyFilter interface. Users can easily create their own strategy filters as shown above.
I understand that you are working on optimizing your system to save processing time.
this is nice things but what is your point of the thread?!
 
I understand that you are working on optimizing your system to save processing time.
this is nice things but what is your point of the thread?!
The purpose of the thread was to communicate to other members specific details as to what I have been working on and get feedback.
 
Son of a b**^^K$HH... this thread has unread messages and I didn't get a notification, this forum ('s software) sucks!

I'm kidding :P Anyways, I usually get a notification if I posted a message on some thread and that thread has activity on it.
 
I'm actually a fan of Fan27, not that that means anything. We had some private conversations but don't worry, it's the same stuff basically that's said in the open. So I'm gonna take the liberty of carrying this further in the open, hoping I'm not hurting anyone's career (albeit I can't vouch the same guarantee for their feeling).

So some guys on this forum who aren't no more in their prime years (I'm neither, being in my 40s), seem to have a genuine interest in finance. Their problem as mine some 15 years ago was that they never ACTUALLY WORKED IN FINANCE so really really guys, you've absolutely no fucking idea who or what you're dealing with.

You're smart and think you know or can know everything, thus the idiotic sales points you're giving me when I'm asking if your primitive stocks trading system does support options. NO PROBLEM you say, not at the moment but options are just one configuration setting away, you just have to add them besides from stocks and you got them, afterall they're more or less the same thing. Well, this is the moment where YOU'VE ABSOLUTELY NO FUCKING IDEA starts from. LIKE NO FUCKING CLUE.

I'm not holding ignorance against you though as long as you're aware you're missing something (like 12+ years doing market making, risk management, data cleansing, position keeping, reconciliation and overall hard, ruthless math) and are willing to learn. I'm obviously missing something too since 12 years of this shit are not enough either to displace the incumbents (Goldman Sachs, JP Morgan, City Bank and a plethora of other names whose capitalization make Google look like some poor 3rd world peasant) or at least get a job at their competitors and by God, the laws of physics say there should be aplenty of them, only where I live it's only THE CORPORATIONS who are hiring or noone else. And obviously they won't hire you to compete against themselves if they're smart enough to realize who you are or else if you happen to make it inside don't ever expect a promotion to a role where you may actually start to be able to be making a difference.

So in all, my 40+ years of experience (plus my last 200 years of continuous successes on top of my 800+ years of recorded history after the Mongols burned down all the previous existing records and invented genocide, and overall living in an area who's seen all and done everything), well they not only not ensure I've a path to walk in the near future (get a fucking job if I quit or I'm fired from the current one), least expect I may actually have the nerve to demand choosing a job that I like (math instead of stupid peasant "bio" food - by the way it's bio because we piss on it prior to serving it to you) or one that God forbid may not just bring me another day (albeit at the taxation level I'm living in it took me 20 years of work to buy one so you do the math) but a whole different Universe: space ships, cyborgs (not the Star Trek BORG peasants but genetically engineered highly intelligent humans who live longer and don't succumb to the first 2000 flu attacks and 20 falls on their head).

So overall here are my lessons so far:

1) Nobody's going to do it for you.
2) If you ain't got no alternatives, you ain't gonna do it either.
3) We (EU and our aborted sister) should stop calling us names and try envisioning what we all know, that if we're to have a path it's gotta be a common one.
4) So
 
I'm actually a fan of Fan27, not that that means anything. We had some private conversations but don't worry, it's the same stuff basically that's said in the open. So I'm gonna take the liberty of carrying this further in the open, hoping I'm not hurting anyone's career (albeit I can't vouch the same guarantee for their feeling).

So some guys on this forum who aren't no more in their prime years (I'm neither, being in my 40s), seem to have a genuine interest in finance. Their problem as mine some 15 years ago was that they never ACTUALLY WORKED IN FINANCE so really really guys, you've absolutely no fucking idea who or what you're dealing with.

You're smart and think you know or can know everything, thus the idiotic sales points you're giving me when I'm asking if your primitive stocks trading system does support options. NO PROBLEM you say, not at the moment but options are just one configuration setting away, you just have to add them besides from stocks and you got them, afterall they're more or less the same thing. Well, this is the moment where YOU'VE ABSOLUTELY NO FUCKING IDEA starts from. LIKE NO FUCKING CLUE.

I'm not holding ignorance against you though as long as you're aware you're missing something (like 12+ years doing market making, risk management, data cleansing, position keeping, reconciliation and overall hard, ruthless math) and are willing to learn. I'm obviously missing something too since 12 years of this shit are not enough either to displace the incumbents (Goldman Sachs, JP Morgan, City Bank and a plethora of other names whose capitalization make Google look like some poor 3rd world peasant) or at least get a job at their competitors and by God, the laws of physics say there should be aplenty of them, only where I live it's only THE CORPORATIONS who are hiring or noone else. And obviously they won't hire you to compete against themselves if they're smart enough to realize who you are or else if you happen to make it inside don't ever expect a promotion to a role where you may actually start to be able to be making a difference.

So in all, my 40+ years of experience (plus my last 200 years of continuous successes on top of my 800+ years of recorded history after the Mongols burned down all the previous existing records and invented genocide, and overall living in an area who's seen all and done everything), well they not only not ensure I've a path to walk in the near future (get a fucking job if I quit or I'm fired from the current one), least expect I may actually have the nerve to demand choosing a job that I like (math instead of stupid peasant "bio" food - by the way it's bio because we piss on it prior to serving it to you) or one that God forbid may not just bring me another day (albeit at the taxation level I'm living in it took me 20 years of work to buy one so you do the math) but a whole different Universe: space ships, cyborgs (not the Star Trek BORG peasants but genetically engineered highly intelligent humans who live longer and don't succumb to the first 2000 flu attacks and 20 falls on their head).

So overall here are my lessons so far:

1) Nobody's going to do it for you.
2) If you ain't got no alternatives, you ain't gonna do it either.
3) We (EU and our aborted sister) should stop calling us names and try envisioning what we all know, that if we're to have a path it's gotta be a common one.
4) So

No feelings or careers hurt Aquarians. I appreciate your posts.

I'll be the first to admit that I am no options expert. That being said, I have built my platform so that complex logic/processing is done external to the platform and my platform can consume the output of said processing. I am not trying to build a platform that can do everything as that is fools errand. My primary concern is to solve my problems and I am doing that. My theory is that I have similar problems as other traders. I expect to be live trading within a couple months and then we can argue over my live equity curve ;)
 
Son of a b**^^K$HH... this thread has unread messages and I didn't get a notification, this forum ('s software) sucks!

I'm kidding :p Anyways, I usually get a notification if I posted a message on some thread and that thread has activity on it.
Yeah, that sometimes happens. It usually means that the software thinks it sent you a notification but you didn't visit the thread. I've noticed that in such cases it might help to unsubscribe from the thread and then re-subscribe to it. That might somehow "reset" the site's notification software.
 
i always wondered why someone didn't create a program that you could draw a equity curve and using vectoring tell it to throw the kitchen sink at it until it find a combination that met your criteria.

No one did because it is a silly thing to do. There are countless combinations of strategies that could accomplish that and choosing any one of those is the definition of bias and over-fitting. Someone also mentioned some software that does this with free trials. Now imagine why that person is sooooooo naive. If you could make money with a 30-day trial of a naive GP program you'd hear the stories of success every single day of the week. Btw I tried just from curiosity and it is one of the most naive softwares I have ever seen. Obviously some people should not be posting in trading forums because they are too silly.
 
Both. Finding profitable algorithmic trading strategies is not easy. Once found, managing those strategies performance and combining them in an uncorrelated portfolio of strategies is also challenging. What makes you say the market for a solution that helps to solve those problems is small?
I don't believe the mkt would be small , certainly not in dollar terms
 
Back
Top