- ago
When using the Dictionary store/retrieve method to reduce history bar fetches from data providers for frequently used symbols, if a symbol match is found, the bars in the dictionary will be out of date. How do the bars get updated to the current bar for further processing, especially when the dictionary retrieve coding is within the Execute method?
0
282
16 Replies

Reply

Bookmark

Sort
- ago
#1
Sounds like overcomplication on top of WL's existing memory/disk caches.
0
Cone8
 ( 25.44% )
- ago
#2
In general for secondary symbols use the new GetPairHistory() method in Initialize() and save the BarHistory result to a local variable or to a Dictionary to organize your [many options] symbols. Now you have a local reference to the updated BarHistory.
0
- ago
#3
Today, after injecting some additional debugging code for the Log Viewer, it appears that the strategy primary symbols (SPY, QQQ), not the option symbols, are not getting updated fast enough with 1-min bars. Hard to believe. Of course, if the primary symbols are not updated, the call to the secondary symbol update never happens, so I don't know if that would be a problem also, if the primaries were updated fast enough.

It appears (from watching the SM log) that WL is on hold while it's waiting for completion of data update request, and it is not completing the execute loop before a new bar appears and it starts over. Can GetPairHistory() help with that?
0
Cone8
 ( 25.44% )
- ago
#4
GetPairHistory isn't going to help.
Since you're using IB, you must be sure to have all your 1 minute histories downloaded and strategy activated before the market opens. It will be able to keep up using Streaming Bars without a problem. If you stop the S. Monitor in the middle of the day while using IB with 1 minute bars and more than a few symbols, just forget about it. Find something else to do for the rest of that day.
0
- ago
#5
QUOTE:
GetPairHistory isn't going to help.
I suspected not.

QUOTE:
Since you're using IB, you must be sure to have all your 1 minute histories downloaded and strategy activated before the market opens.
Check.

QUOTE:
It will be able to keep up using Streaming Bars without a problem.
That has not been my experience. I can get it running properly for an hour or two and then something happens, and it misses multiple 1-min bar updates. Possibly it could be one of my other intraday strategies kicking in on a 30-min or 60-min interval that breaks its back.

QUOTE:
If you stop the S. Monitor in the middle of the day while using IB with 1 minute bars and more than a few symbols, just forget about it. Find something else to do for the rest of that day.
Wow, that is quite a statement! Unfortunately, it has not been easy to avoid situations where WL has to be restarted.

It's sounding like my experiments with automated trading have been a good investment. I know now the code works, but unless the data source is high performance and reliable, you cannot leave these strategies running unattended.

Is there an option (other than Tradier as a candidate) to get higher performance bar data response for stocks, indices, and options and decouple the data from the broker?

BTW, I have found TDA to be pretty good on data response, but it appears to be very stingy about the amount of intraday data you can download in a short period of time, before cutting you off.
0
Cone8
 ( 25.44% )
- ago
#6
Because I have some insight to what you're doing, I'd bet 10:1 that your problems with the 1-minute overruns aren't because of the primary symbols - these will update without any problem.

Rather, you're making multiple requests to secondary symbols and IB is throttling your data. Once you've made more than a few data requests in a few seconds, you'll only get a maximum response of 1 request every 6 seconds, and eventually (like you found yesterday) they may just cut you off.

Consequently, if you have a strategy that is making just 1 GetHistory request per run , it's only going to work for a maximum of 10 symbols and then you're going to blow past the 1 minute timeline.

Here's something that might help, and frankly, I didn't realize it until yesterday. GetHistory and GetPairHistory request "a lot" of history and caches it for fast access later. In other words, the chart range doesn't control it. If you need to use "GetHistory" for 1-minute bars from a provider like IB, you better make sure you do that pre/post market to seed the cache.

For quicker, ad-hoc requests for new symbols, use the WLHost.Instance.GetHistory to control the range. If you only need a couple days of data to work with while trading, this may be the way to go. You can even overload GetHistory() in your Strategy just by adding a routine like this, which requests just 2 or 3 days of data and then syncs.

CODE:
private BarHistory GetHistory(string symbol, BarHistory syncBars) {    BarHistory bh = WLHost.Instance.GetHistory(symbol, syncBars.Scale, DateTime.Now.Date.AddDays(-2), DateTime.Now.Date.AddDays(1), 0, null);    return BarHistorySynchronizer.Synchronize(bh, syncBars); }

This still creates requests (and the 1 request per 6 seconds will still apply for IB), but it won't get lost requesting all data history, 1-day at a time, which will appear to you as a frozen U.I.
0
- ago
#7
Thank you @Cone for your insights.

QUOTE:
Because I have some insight to what you're doing, I'd bet 10:1 that your problems with the 1-minute overruns aren't because of the primary symbols - these will update without any problem.


I might take that bet.

The reason is that yesterday I added additional debug output to the Log Viewer to try to understand why some apparent (on a streaming chart) signals were not being taken. The addition included the actual values being test. I was surprised to find that these values were NaN when trades were not taken.

The signal is based on comparing current bar values of an EMA series run on SPY and QQQ (the underlyings), very similar to a crossing indicator. This series is created and updated in the Initialize() method.

The Execute() method, where the signal is tested, does not run until Initialize() has completed, at least based on my growing--but still limited--understanding of a strategy execution https://www.wealth-lab.com/blog/anatomy-of-a-wl7-strategy. Therefore, if Execute() is reporting that it is testing NaN values, I concluded that the updated values for the underlings on the current bar were not available when the Initialize() method was run.

Is my understanding of the process correct and my conclusion logical or am I missing something? I do not have insight into what is happening to the strategy execution when WL is waiting for data updates. The data updates it is waiting for (which takes about 45 seconds for two symbols when it actually works), does not appear to be waiting on the option data. It appears to be waiting 45 secs. for a single bar of 1 min data for 2 symbols. When there is a NaN result, there is no processing of requests for option data, just an exit from the Execute() method.
0
Cone8
 ( 25.44% )
- ago
#8
Let's see the code. Don't make me guess.
Make a minimal example.
0
- ago
#9
Part2

It is important to note that the 1-min strategy discussed above ran perfectly (although slowly with 45 second update times) this morning until 10:30 market time. At that time my 1-hour strategy kicked in, requesting the first hourly update of the day on ~70 symbols. (It should only request only 1 bar for each symbol; I'm not clear what it actually requests). That's when IB data essentially stopped working and prevented my 1-min strategy data updated from being processed as well (for around 30+ min).

These two strategies apparently have to be considered jointly (and at least one or two more dailies) when it comes to data demand. It appears that it is my 1-hour strategy that is now creating a pacing violation. This is disconcerting, as this strategy used to run without creating this type of problem.

I realize that multiple improvements and releases have been made to the IB API recently. I have some insight that behind the scenes, WL is now making more data requests to IB to improve the accuracy of the option symbol requests. I'm wondering if this may have contributed to pacing violations that didn't occur two weeks aga, with the same, untouched, 1-hour strategy.
0
Cone8
 ( 25.44% )
- ago
#10
What is the 1 minute strategy doing?
If it's using GetHistory() then that's going to be in contention with polling requests for the hourly strategy. This happens near simultaneously on different threads, but there's only 1 IBHistorical.Instance that everything has to wait for. IB doesn't care to give you a bunch of data quickly.

How about using a different provider to alleviate the strain on poor IB. It's just not made for your kind of data demand. Haven't we stressed this enough?

The IB Provider queries to return a valid option contract symbol are light - we're just checking the "HeadTimeStamp" which indicates the contract has traded,. But it just occurred to me that we can even alleviate that request for contracts that have locally cached data. .
0
- ago
#11
QUOTE:
What is the 1 minute strategy doing?

1. Running 1-min bars on SPY and QQQ
2. Creating EMA series on these symbols close prices
3. Comparing current EMA's for each symbol for crossings
4. Buying, selling, or holding based on crossings and whether position is null

Very standard stuff.

QUOTE:
If it's using GetHistory() then that's going to be in contention with polling requests for the hourly strategy.

Here is the code that retrieves the option bars. Yes, it does use GetHistory(). Should I be using a different method?

CODE:
      private BarHistory RetrieveOptionBars(BarHistory syncbars, string symbol)       {          BarHistory obars;          if (_dict.ContainsKey(symbol))             obars = _dict[symbol];          else          {             BarHistory barHistory = GetHistory(syncbars, symbol);             obars = barHistory;             _dict.Add(symbol, obars);          }          return obars;       }

QUOTE:
How about using a different provider to alleviate the strain on poor IB.

I'm not sure if you mean "poor" as it's not very good, or you feel sorry for it because I'm abusing it :)

I would appreciate your recommendation for another data provider I can try, especially given what you know about my requirements.

QUOTE:
If you stop the S. Monitor in the middle of the day while using IB with 1-min bars and more than a few symbols, just forget about it. Find something else to do for the rest of that day.

(Post #5)

I thought that was an exaggeration but today I see what you mean. Based on my experience with IB over the last few days, including today, and the additional "internals" insight you provided, I have a somewhat modified conjecture of what is happening. Once the apparent pacing violation locks me out (my first 1-hour data run at 10:30 market time) my 1-min strategy stops working, because, as you noted above, it is waiting for the 1-hour data update / strategy processing to complete, which could take 20 minutes (if the 1-min strategy was not already running).

This starts a chain reaction, where the 1-min data and processing get 20 bars behind, and apparently can never catch up, meanwhile not even returning values for SPY and QQQ for each 1-min bar. The strategy is dead and may not come back to life without a WL restart, which compounds the problem even more, by deleting dictionary data putting more demand on IB to update bar history.

I am going to try running these two strategies at different times to see if that helps avoid the problem. It already appears the 1-min might run OK if nothing else is requesting data. I will try the 1-hour strategy with 1-min deactivated and see what happens.
0
Cone8
 ( 25.44% )
- ago
#12
SPY and QQQ are just trading their own histories on 1-minute streaming bars? And 60-minute polling is interfering? I'll have to try that.

Or did you mean that SPY and QQQ are actually hitting GetHistory for option trading? That's not "standard stuff" and we've already beaten that horse.

I spent a lot of time putting the necessary information in this article for everyone to make their own data decisions (and so that I don't have to keep typing the same thing)
All About WealthLab Intraday and Realtime Data Providers
0
- ago
#13
QUOTE:
SPY and QQQ are just trading their own histories on 1-minute streaming bars?

I don't know how to answer your question, so let me describe the strategies we have been discussing. One strategy uses 1-min data on SPY and QQQ to generate signals to trade options on the underlying. A second strategy runs 1-hour data on ~70 symbols to generate signals to trade options on the underlying. Is that what you were looking for>

QUOTE:
And 60-minute polling is interfering?

I'm not qualified to answer that. That is what you suggested might be happening.

QUOTE:
Or did you mean that SPY and QQQ are actually hitting GetHistory for option trading?

I think I see what you are asking. I am not using GetHistory() to update SPY and QQQ every minute. WL does that for me since those are the two symbols in the 1-min DataSet.

QUOTE:
I spent a lot of time putting the necessary information in this article for everyone to make their own data decisions (and so that I don't have to keep typing the same thing)

Of course. I understand and completely agree. Thanks for compiling this. I've archived the bookmark.
0
- ago
#14
QUOTE:
I am going to try running these two strategies at different times to see if that helps avoid the problem. It already appears the 1-min might run OK if nothing else is requesting data. I will try the 1-hour strategy with 1-min deactivated and see what happens.

Post #5

I tried running 1-hour strategy (~70 symbols) after leaving WL off for about 30 minutes and restarting. It looks like it started running OK and successfully processed several potential option trades based on signals. After 5 minutes, it locked me out and wouldn't return additional data. I don't know if that is because I was already locked out today and now I'm on a shorter leash.

As I have noted in a recent post, I can tell from the Log Viewer that there are many more "errors" reported by IB than I have seen in the past. As you previously explained these are not errors, but "normal operation" as WL searches for the best option strike.

However, it does indicate a significant increase in "valid" requests to IB over the same timeframe, which may be intruding on the pacing threshold.

I will run 1-hour strategy tomorrow fresh, with 1-min strategy deactivated, and if it fails the same way I will have to conclude something external to the strategy has changed (on the WL side or the IB side), since I didn't have this problem before.

It's frustrating that IB doesn't just tell you when it's locked you out and when you can try getting data again. It's been difficult to pinpoint where the problem is originating. I don't think it's in my code but trying a proven provider will help determine that.

At any rate, I don't expect tomorrow's result will change the need for me to find another data provider if I want to use these strategies.

0
Cone8
 ( 25.44% )
- ago
#15
QUOTE:
I think I see what you are asking. I am not using GetHistory() to update SPY and QQQ every minute. WL does that for me since those are the two symbols in the 1-min DataSet.
You didn't even say what method you're using to update SPY or QQQ. How does 'WL do that for you'? Polling? Streaming? Streaming Bars?

But this misses the point entirely. I don't care about updating 2 symbols. I care about hitting GetHistory() multiple times for secondary symbols. I'm asking if the strategy, whose primary symbols are QQQ and SPY, is using GetHistory(). The answer is yes, because you revealed that in Post #11.

You're already trading 70 symbols using polling - I ASSUME.
Don't do that with IB. It will take about 6 minutes just to poll for 70 symbols.
If you're going to trade 70 symbols using IB in the S. Monitor, USE STREAMING BARS. This will finish in 10 seconds and not hit IB with 70 requests.
Sorry for yelling.

Lastly, for your live option trading, do you actually need to know the option price? If the answer is "No" and you're using Market orders, then you don't even need to request their history. You can create a dummy BarHistory object to use to fire off the trades without GetHistory() requests and 0 delay.
0
- ago
#16
Started strategy #2 (1-hour data) today at 10:30 market time with 1-min strategy not activated. It ran for about 3 min and processed 5 symbols before locking out data. During that time IB issued around 310 messages to Log Viewer

"Can't find IED with tickerid ....."r.
0

Reply

Bookmark

Sort