This thread is meant to continue the development of the In & Out strategy started on Quantopian. The first challenge for us will probalbly be to translate our ideas to QC code.
I'll start by attaching the version Bob Bob kindly translated on Vladimir's request.
Vladimir:
About your key error, did you also initialize UUP like this?
self.UUP = self.AddEquity('UUP', res).Symbol
Mateusz Pulka
About live trading and follow yahoo data. @Alex Rehf Nathan Swenson I was compering close prices from finance yahoo vs close prices from quantconnect there are small differences and because of that signal about in/out is not at the same time as in backtesting.
Diary Of A Finance Kid
Alex Rehf I have used Yahoo Finance data and over a long period of time it becomes very innacurate on some assets/securities. Daily close prices are sometimes different and they even sometimes assume/fill in the gaps on dail close prices. I personally would not trust them as a data provider.
Someone in a Quantopian thread once said "Garbage In, Garbage Out" and this phrase has resonated with me. We have all seen how different returns of the same algos are just from swithcing from Quantopian to QuantConnect.
Peter Guenther
Mark Reeve: Welcome to the discussion and thanks a lot for joining in! Your suggested code modifications sound amazing in terms of achieving greater backtesting efficiency and additional improvements. Regarding your points above:
Peter Guenther
Elsid Aliaj: Thanks for sharing the gold results, much appreciated! I was thinking that your idea regarding the switch to gold as a third option might integrate nicely with Mark Reeve's idea concerning the dimmer. For instance, when things become extreme in terms of many signals (maybe 2+ is already enough) saying 'out' one might switch to non-bond assets such as gold or other precious metals. This will definitely be worth a try!
@all: also thanks for pushing hard on the live trading front, much appreciated!
Jack Pizza
Peter Guenther Mark Reeve awesome ideas, I think the 3rd option can just be the ultimate out of just cash or gold even gold we don't know how it will perform. As were only using 12 years of backtest data. Sometimes good goes through 400 year bear markets.
I think the best would be insuring the portfolio for tail events with say 1-3% of the account with OTM options.
The strategy can afford the insurance and performance "drag" to literally lower drawdowns to a measly 6%, plus you make up the drag when the black swan events strike, and you'll be out ahead.
These events are happening more and more often it seems like almost 1-3 years now. We've had major vix blow ups multiple times, corona, multiple hard sell offs.
It's basically like free insurance since probability wise you'll hit it and breakeven on the insurance for all the years you used it.
Jack Pizza
Also regarding the extreme readings you'd probably have to test various hypothesis and have various logic in there.
Because maybe the extreme readings can happen at the start of an uptrend and would indicate a strong starting move, or happen near a top and indicate exuberance, or maybe just a continuation.
So seems like a lot of data analysis has to occur to make a meaningful conclusion at what the 1% percentile readings actually mean.
Nathan Swenson
The only problem with this Dimmer approach, you would need the algo doing the trades as more management needed. The current setup is nice because the trade count is so low. It's no problem to just do the trades manually with around 10 trades per year. Hell, someone could just post the signal in a forum post and it would be sufficient. I don't really have a way to connect QuantConnect to my TD Ameritrade nor to my NinjaTrader.
Hmmm, now that I think about it, can QuantConnect send emails? I think my NinjaTrader can trade with email signal. That would be cool because my Ninja can also trade my TD Ameritrade account.
Mateusz Pulka
Generally to make it works outside Quantconnect is quite challenging because of differences in source data. I was tested finance.yahoo, alpaca and polygon. And each provider has some diffrences in close prices and bacuse of that the signals for in/out are different. Prices from polygon was close to quantconnect, but they don't adjust data for dividends, only splits.
Spacetime
Jack Pizza
Nathan Swenson You can write a script with any sort of selenium library to check orders everyday, and then login to your email provider and sent out an email.
Peter Guenther I copied your other version where it fixed an issue with holding both in/out positions. I ran it live again today, well paper trading, and it again sent buy orders for both in/out.
So buy QQQ, EIF, TLT, GLD.
IS this the issue since it's set to 1? Would setting it to 0 fix it?
self.be_in = 0
something funky is going on.
Mateusz Pulka
It is a bug in the code Elsid Aliaj.
Here is the correct version of algo
Jack Pizza
Hey gpw radar that is the version I am using and still send buy orders for both in/out when running live.
Peter Guenther
Elsid Aliaj: gpw radar found that we need to add tabs to the part where it says "#Thoma's reducing unnecessary trades" (and the following lines). If you put this part inside of the if clauses (via adding one tab per each line), both in the 'rebalance when in' and 'rebalance when out', then the code should work OK. The issue is that at the very beginning, in the Initialize part, we define a dictionary with all the holdings. Then it goes to the 'rebalance when out' part which runs daily and runs the 'Thomas's reducing unnecessary trades' part, resulting in the algo ordering the entire dictionary (i.e. all holdings, in and out). This should be fixed when you 'hide' that order part inside the if clauses via adding the tabs per each line. Hope this makes sense.
For future code, I will add a line in the Initialize part that sets all of the dictionary holdings to zero, just to be on the safe side ;)
Jack Pizza
Peter Guenther yeah a tad confused, so I removed a tab from the minimum order stuff is this what you meant?
def rebalance_when_in_the_market(self): # Swap to 'in' assets if applicable wt = self.wt if self.be_in: # Close 'Out' holdings #for asset, weight in self.HLD_OUT.items(): # self.SetHoldings(asset, 0) #for asset, weight in self.HLD_IN.items(): # self.SetHoldings(asset, weight) wt[self.STKS] = 1 wt[self.TLT] = 0 wt[self.IEF] = 0 wt[self.GLD] = 0 # Thomas's reducing unnecessary trades for sec, weight in wt.items(): cond1 = (self.Portfolio[sec].Quantity > 0) and (weight == 0) cond2 = (self.Portfolio[sec].Quantity == 0) and (weight > 0) if cond1 or cond2: self.SetHoldings(sec, weight)
Peter Guenther
No worries! It would need to look like the below. See the indent of the "Thomas's reducing unnecessary trades" part (the whole block is indented more so that it falls 'within' the if clause). You would need to make the same adjustment where the other "Thomas's reducing unnecessary trades" block is in the code (i.e. where you swap in the 'out' assets).
# Swap to 'in' assets if applicable wt = self.wt if self.be_in: # Close 'Out' holdings #for asset, weight in self.HLD_OUT.items(): # self.SetHoldings(asset, 0) #for asset, weight in self.HLD_IN.items(): # self.SetHoldings(asset, weight) wt[self.STKS] = 1 wt[self.TLT] = 0 wt[self.IEF] = 0 wt[self.GLD] = 0 # Thomas's reducing unnecessary trades for sec, weight in wt.items(): cond1 = (self.Portfolio[sec].Quantity > 0) and (weight == 0) cond2 = (self.Portfolio[sec].Quantity == 0) and (weight > 0) if cond1 or cond2: self.SetHoldings(sec, weight)
Alex Rehf
Hi,
i modified the logic a little bit (i used a version from quantopian, i think it was valadimir, who posted this).
Nathan Swenson
I see potentially an issue with this system. It is based on cycles, but there are no historical sync points. So basically if you turn it on mid cycle, you will get completely different results than if you had turned it on a week or 2 earlier. I believe it would be better if at start it does a lookback to reach a sync point for optimum cycle entry and performance. That way everyone is seeing similar performance, not linked to when in the cycle you start it.
I should add, I observed this by turning it on live. I see that it took the TLT trade today, while if you look at a run from 2008, you'll see that the TLT/IEF trade was on 10/6. The results that follow will likely not match with other.
Peter Guenther
Nathan Swenson: Just speculating here, since I am still getting my head around how things work on the QuantConnect platform; however, could this be related to the concept of the 'warm-up period'? That is, the algo might need a command in the Initialize sequence where it is told to pre-load 252 days of historic data so that it can calculate the signals properly (esp. the returns sample on which the percentiles are based). This might be related to your observation regarding what is happening in live trading (?).
Nathan Swenson
Thanks Peter! I believe you are correct. I have added the following warm up code. Hopefully this is sufficient to synchronize the historical data:
# set a warm-up period to initialize the indicator self.SetWarmUp(timedelta(252))Nathan Swenson
Unfortunately setting warm up period is not sufficient. Looks like you need to evaluate the bool self.IsWarmingUp and only allow logic to run once the bool is false. This issue will affect not only live trading, but also backtesting. You can verify this by backtesting from start date of 10, 1, 2020 for example where you'll see a QQQ trade immediately on 10/1. Or if you start on 10/8, it immediately trades into TLT/IEF. These trade dates do not match up to a long term test. I am no good with Python and not quite sure the right way to implement this warm up check. Is anyone actually doing it the right way? I checked all the versions here and do not see warm up considered which means the startup is not quite right. You'll end up with differing results just shifting backtest start date by a day or more. Ideally I would expect the algo to wait for the next cycle start to enter.
Tentor Testivis
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!