Hi my name is Jared Broad, and I'm the founder and CEO of QuantConnect.
Today we're going to be doing a slightly different video where we're going to be
looking at some of the recent movements in the market and then trying to test
some of those ideas that we've picked from the current trends and themes that
we're seeing and testing them and building a strategy on them in QuantConnect.
So the idea is for us to explore a hypothesis and to test that hypothesis
in the platform, and then see if we can see how it goes and implement it in a
fairly raw way where you can see how we go about the process of debugging and
fixing those challenges and building that strategy from scratch. So there's
probably gonna be a lot of bugs, and I'm going to try and be very transparent about
how we're going about evaluating and building the strategy, and yeah I'm glad
to have you with us. Let's get started the topic that I was interested in
recently was this theory called risk parity. Since about the 90s there's been
a strategy where you do an allocation to stocks and bonds, and depending on the
the breakdown of that you can apparently mitigate your risk. A lot of the funds
which were based on risk parity strategies suffered in the very recent sell-off in
March because the theory is that when the stocks fall bonds normally rise, so
the challenge is though that in March we actually saw stocks and bonds fall
simultaneously. The strategy people claim that it broke down, and that it's
kind of like this underpinning core thesis to all of the robo-advisors that we
see today, and a lot of the very large funds like AQR and Bridgewater they're
all based on this risk parity idea. Let's test that theory and specifically I came
across this fascinating thread on twitter by Corey Hoffstein. He is
suggesting that rather than having a strategy which is just fixed 60/40
between bonds and stocks that you should
actually do rebalancing in small amounts and frequently. Imagine that you
take your $100,000, you put $60,000 into stocks, $40,000 into bonds, and
then a year goes past and your stocks have increased in value, and the bonds
are about the same. So you actually need to readjust your portfolio to get it
back to an equilibrium which is 60/40 in stocks and bonds. A lot of the
questions people ask about this sort of strategy are when do I rebalance? How
frequently do I rebalance? Do I rebalance every day, and how many fees do I get
from rebalancing so frequently? So these are all things that we can backtest.
Let's take this as our thesis that doing traunched rebalances as in you don't
need to rebalance your entire portfolio but rebalance say 1/12th of your portfolio and
do it every month. Do it frequently in relatively small amounts to get the best
performance. So this is based on research published by AQR. We can see here that
depending on the rebalance mechanism you can get very substantially different
results. Using a platform like QuantConnect we can go in, and we
can just set up an easy experimentation framework where we can test all these
different ideas. Let's start there, go to the algorithm lab. The key insight from a
strategy like this actually doesn't change. You have a 60% weighting
on stocks, and a 40% weighting on bonds.
So there's actually no need to do any sort of intraday insight creation or
anything like that. We're just going to keep it very simple
and make a universe which is the S&P 500 via the SPY ETF, and a bond ETF, and then
have a fixed insight that goes for the whole period because there's no actual
change to the strategy. So firstly we want to try and choose a period which
covers as long as possible. Ideally we could get the 2000 crash,
the 2007 crash, and then the current crash that were in now so that we could
see how the strategy performs. This is also probably best tested on a larger
capital base, so we can increase that to a million. Here we can create our universe.
Universe and portfolio construction, and we can pull that from the documentation.
Big fan of not needing to remember this stuff, so you can just paste in a
lot of this from the docs. So this is actually pretty close to what we want, so
here we're going to be using daily resolution because we could be
backtesting very long periods very quickly, and then we want an index ETF, and the
bond ETF. So what should we use as our bond ETF? We want something with a
very long very long track record, and we can go to the ETF DB, and we can see
a listing of whole bunch of bond ETFs. Here we've got the biggest one by volume
here is AGG, so let's open a few of the high volume ones and see which one
might suit us. The general rule of risk parity is to get something which
is more about government Treasury bonds not corporate bonds, so we can skip
the corporate ones here. SHY, okay and then there's no hard and fast rule here
or if there is I'm not familiar with it, but we might pick an ETF which allows us
to test a long period. So AGG is September 2003. 2007 for Vanguard,
and SHY is 2002, so maybe we can use SHY to kick us off.
Okay.
So we've made a universe, let's just get a basic equal weighting algorithm
running, and then we can come back, and we can start building our
hypothesis after that. So let's go to execution, we just need an immediate
execution model, and we can go to portfolio construction, and to kick this off
let's just use some of the stock portfolio construction models here.
This is just the equal weighting portfolio construction, and we can just throw that in.
In Alpha here we can just take the constant alpha model.
Okay, and then the last one here we don't actually need to set, but just
for completeness let's set the null risk execution. Okay, so this is just the
absolute basic framework algorithm, so we're going to build this framework
algorithm from these stock components and just have a SPY and SHY, and because
of the way that we've coded this we're using an equal weighting portfolio
construction model, so this is going to be 50/50. This is just to get us running,
to get the the basic algorithm running, and actually this won't work
because SHY as we saw has an inception date of 2002. Let's start the backtest
from 2003. SPY has been around forever, so we can start from 2003 and
run a backtest from there.
Alright great. So we're off the ground. We've got this thing placing trades. We
can see here there's an equal allocation between SPY and SHY, and then you can
see down here we're doing a lot of insights, and you can see from the fees
we're doing a lot of trading. The default rebalancing models, the default in the
framework is this daily rebalance, so we can start looking at ways to firstly get
our 60/40 weighting, and then also to reduce the rebalancing so that we're not
doing daily rebalancing and costing $9,000 in fees for such a simple strategy.
Let's start with getting the 60/40, and then we can do the rebalancing fix after
that. Probably a nice way to do this in the framework is to use a model which
ships with LEAN. It's the insight weighted portfolio construction model,
and that will just allocate capital according to the weights that are
assigned on the insights. With a framework model there are these insights that
are generated which are predictions and it's supposed to set the the direction of the
portfolio, and so for this because we have the same allocation forever we can
actually just produce an insight forever that's exactly the same, and we'll say we
want 60% on stocks and 40% on bonds. To do that it's probably easiest to
create our own alpha model. So we can come to the documentation here, and we
can copy just the basic scaffolding.
We can say here risk balance alpha, and we
need to do some work and return insights.
Okay, and then here we're not going to have a whole bunch
of security changes here, so we can just pass, and use this as our new alpha.
We're going to set our alpha as this risk balance. We have here SPY and
SHY, and so this is just a simple array, and this is zero and one, so let's pass
that in because we could have our assets configurable.
So this would be SPY, this would be SHY, and then we need a constructor here
to catch that.
And so we can pass in the two symbols that we want to create a insight for.
Let's save those two.
And then probably because this is going to be a very simple insight,
we can actually just create insights here. So we can say self.insights
equals something, and then we'll have insights here that we can return,
and we'll return them here. So now we just need to create some
insights which are weighted. So we can go to the docs here, Creating Insights,
We can see the creating an insight class here.
Here's an example of creating a weighted insight.
So, insight.price, take this here and paste it in. And so we want to
create an insight of 60% for the risk asset and 40% for the safety asset.
Okay, risk and safe, and then we're running this backtest since 2003 let's just say
20 years, so we're going to say days equals 20 times 365. The idea here is
we're just going to create an insight which lasts for twenty years and is
going to be 60% SPY, and 40% safe, and then we'll do all of the work in our
rebalancing code after that. So, we've created these insights.
Let's return them here.
Let's just do a quick test of that.
Okay, cool. The code's built and running. We haven't finished coding, so obviously
we expect it to not be quite trading the perfect balance yet.
The next step is we're emitting these insights with 60/40,
but we have set here a equal weighting
portfolio construction model which isn't built to respect them. So we have
somewhere in LEAN an insight weighted portfolio construction, so the
best way to find out would probably just be to go to LEAN, and we've got a bunch
of these modules underneath the algorithm framework here. Under
portfolio and then insight weighted portfolio construction model. The Python
implementation here. And you can see we've coded up the implementation to do
a portfolio construction model weighted by the insights themselves.
So we've set that here and test that. Let's see how we go.
Okay cool. Once the backtest is done we should
probably do just a really quick sanity check. So we haven't even started on
doing the rebalancing frequency yet, but we'll get to that. So the first thing we
might want to sanity check is the simple 60/40.
We do some quick napkin math.
Here we've got 9,000 shares filled at $63 dollars for SPY.
9,550 times $63 dollars, and so we're seeing
$600,000 allocated in our first trade to SPY.
That lines up with what we're expecting, a 60/40 weighting, so of the
million dollars in the portfolio when we started the very first trade is setting
it to be six hundred thousand. So it's a good start and then the next point
before we get onto traunching and looking how to optimize this, let's look at
getting the rebalancing under our control. So there was a recent discussion
in the community about this, and we went into a relatively new feature here, so we
can actually now, using the portfolio construction models we can disable the
automatic rebalancing and make it use completely manual rebalancing. The
first step to that is disabling this rebalance on insight changes. So that
means before, typically by default, it would rebalance when an insight expires,
or when you added a new insight to the portfolio. By using this you're saying
don't do any rebalancing on those new insights, and then secondly rebalance on
security changes which is when a new security was added to the universe,
trigger rebalance. So both of those things are disabled.
And then finally the third thing which was discussed here, too, is using a
rebalancing function. A rebalancing function is a function which will return
the time at which you should do a rebalance. So this allows you to build
some sort of rules into for example monitoring for portfolio deviation or
monitoring for some sort of trigger that you want to use to trigger that
portfolio rebalance. So that's just the function, and you can pass it in to
the portfolio construction model, and then when you return a time it will
rebalance on that time. Otherwise if you return none it will continue asking you
until you give it the time to rebalance. We actually have an example here.
Again on GitHub.
You can see here it's simply just passing in the function. So we want
to define the function here in our code.
We can see this rebalancing example function here.
This one's a much more complicated one, but the keys that we
need to take away is that it has a time here, and you can return none. So let's
just copy something simple here. Constantly return none. Sometimes I like
to just run backtests to sanity check things. In this case we've changed
our code to prevent all rebalancing, and so a nice sanity check
there would be to run a backtest and see nothing happen. And that way we can
just know that we're in complete control of when the algorithms doing
rebalancing. So you can see even though we've got hundreds of insights
we're not doing any trading whatsoever. That's a great start. We're now
in control of the portfolio, and we're generating insights.
One thing that we might want to check here,
this is emitting hundreds of insights; there are two every single day, and the insights are
for twenty years, so really we don't need to emit thousands and thousands of these,
and it's just a huge waste of energy. Let's update that, so we're going to say..
We're going to detect if we've already emitted the 20 year insights, if we've
already emitted them then just return nothing. Otherwise set our flag, and
then emit the 20 year insights once. The idea would be that we would get rid
of all of this noise that are emitting for years and years, which is presumably
going to slow things down. So let's sanity check that and run a backtest.
Cool, so we see here we've got exactly one prediction for each one, and we've
got one trade here. The very beginning of our backtest, and so that's exactly what
we wanted to do. Now when should we rebalance? This is the key, this is what
everybody's talking about for their 60/40 models. Let's try the basic. What most
people do is some sort of time rebalance of their entire portfolio, and if you
recall the thesis was that to do a time rebalance of 1/12 of the portfolio.
Every month rebalance a fraction, and so over a year period you would be
eventually fully rebalanced. We'll get to that partial rebalance. At the moment, these
insight weighted, all the portfolio construction models that are included
rebalance the entire portfolio, so we can start by simply getting this to go
every month. If we get this going every month then we can work on the
rebalancing a fraction of the portfolio after that. A very simple way to
detect month changes would be to literally detect the month change. We can
also, on all of the portfolio construction models they take date and
time schedule rules, which is automatically handled by QuantConnect,
that when the month changes we can trigger a new rebalance. Just for
simplicity, and so that you can fully see how this is under your control we
can say month, and do this here. Do something like this. Just if..
This is skipping any scheduling rules here, we're just creating this,
initializing this flag at negative one and then it's always a good idea to
handle the starting case, the null case we're here detecting the negative one
and returning the time, and then here we're saying that if the month changes
that the current time changes, then set it and return the time.
Otherwise do nothing. So we would expect this once a month to do rebalancing of
the entire portfolio. So let's see how it goes.
Okay so we have it trading again, and
our rebalancing function is triggering trading, and the though bug that we're
seeing is that it's trading every single day, so we're seeing the same $8,000 in
fees that we saw before. So let's dig into this, and see where I got it
wrong. Look at this. If the month is equal to -1 just return time and
don't do anything else. So we need to set this here. So this will handle our default
case, and then the next time around we'll come through and set this properly. Okay.
Hopefully we see, what we'd expect now is to see the fees drop from $8,000 down to
something more manageable, and then we can verify that with the trades and
check each trade. So already the backtest is finished, we've
seen the fees drop from $8,000 to $500 so we're probably doing fewer trades. cool
And we can come down here, and once it's done.. cool.
Let's look at the trades. Okay on the first of January
we've done some position sizing, and then you see here the first of February, March,
April, perfect. So you can see here the the large trade occurred at the very
beginning, so this is opening our initial portfolio, and then the subsequent trades
are relatively small because it's just a slight rebalancing to maintain the 60/40
split. So that's good, that's a good foundation to build from. We have
relatively low fees, we have monthly rebalancing, we have the 60/40 split.
The last piece here is the traunch rebalancing. So instead of rebalancing
the entire portfolio every single month the thesis by Cory was that the best
portfolios are if you rebalance them a fraction of them every single month. The
expense of rebalancing the entire portfolio is probably too high, and so
you might be able to save costs by only rebalancing a fraction. So it's kind of
like this hybrid of dollar cost averaging where you buy the dips on the
way down and risk parity. So let's see if we can try and get that technology into
this algorithm. So there's nothing built like that ready to go in QuantConnect
for you so the only thing we can do is take the existing portfolio construction
model and try and improve on. Here we're using an insight weighted portfolio
construction model. Let's use that as our foundation and create something off that
to achieve the 10 or 12% rebalancing each month versus rebalancing
the entire portfolio each month. So this is the Python code for the
insight weighting portfolio construction model, and we want to try
and use this as our foundation and build off that. You can start just by
copying this code. So this is all open source, this is inside the LEAN framework
folder here under the portfolio construction models, and so we can come
into our algorithm, create a new file, and we're going to have our own portfolio
construction file here. I always like to delete a lot of the noise, too many comments
for me, so we can trim this down.
Okay cool. Let's just start by renaming this.
We'll call it our traunch portfolio construction model.
Put this here, and we need to import this.
from our code import everything. Sorry. So this is our portfolio file so from
portfolio file input star, so this is gonna be all this, and then before
this is the insight weighting portfolio construction model. So before it
was extending the equal weighting, so unlike the equal weighting the insight
weighted just uses a slightly different weighting, but rebalances the entire
portfolio anyway. So what we're doing here is quite different we're going to
only rebalance a fraction of the portfolio every month, so we can extend
from this and try and tweak it to what we need to do.
The core of how these work firstly it gets the list of active
insights. So the portfolio construction models don't need to worry about
generating those signals they just take them from the alpha model. Then it
goes back to here, and it determines the percent of the portfolio we should
allocate to that asset, and in this particular case it's an array
where we group the insights, and in a double weighting that we assign to those
insights. So we are determining the target percent here, and so in our
example we're going to have a portfolio that was say started out at 60%
and then over time it's drifted to 80% on stocks
because the stocks have gone up in value, so we need to find the difference there,
so we need to find 80 minus 60, and the 20% that we need to move we
need to do that slowly. So before we were doing all of that 20% rebalancing
in a single traunch, so now we want to try and take this 20% and do it over
a slower period. To do that we can probably start by calculating the
difference here and then get a factor to apply to discount the full move because
we don't want to move the full 20% in one trade. So here we
can even say for example, this is going to constantly say that we want
60/40 on those two insights, and we could actually just edit the results here, so we
could do something on the previous calculations to slow that migration so
that it doesn't occur in a single trade that occurs in many trades. So it's a bit
of an approximation, but I think just multiplying it by a factor to slow it
down would be good enough for our testing. For example this can be
our benchmark, and perhaps we want to pick a specific period which will show
some pretty significant rebalancing. So here if we look at say the period from
September to October 15th or September first. Maybe March.
Yeah March to April 2009. This period has got a very significant rally,
and so it'll trigger a very significant rebalance. So we can probably
see that in the trades from 2009 if we increase this just so that we can get a
sanity check on our our code that it's working as expected.
You can see that here so March to April we see large trades of stocks
both directions in a single month.
We dramatically increase our position and dramatically decrease
it the very next month. So this is a nice example case of the rebalancing causing
churn in the portfolio going one way then the other and triggering lots of
fees when there's only been a very short time, and that's something that this
style of traunch rebalancing might be suitable to to improve.
Let's have a look, keep this in mind. We'll come back to this one here.
We see 480 and then 300 the very next month, -300 the very next month.
Actually, so after doing some thinking about
how this code would look after we try to heck it in to
where we need it to be I think it might actually be simpler in cleaner to leave
the insight weighting portfolio model and to do this with a slightly different
approach. Instead of us adjusting the portfolio targets each
month the portfolio target is relatively static it's 60/40, and the goal is to use
100% of the portfolio. The difference is though that by doing it in traunches were
effectively executing that vision slower. So instead of just executing 100% of it
every single time immediately when the portfolio comes through we're going to try
taking the targeted rebalance, and then reducing that by a factor and executing
that reduction. So the hope is that by doing this by the time the next month
rolls around if there's a big event like 2009 where there was a major rebalance
one way then the other way, because we had that slow rebalance we won't have
made a shift in the wrong direction too quickly. With that slight change in tack
let's go back and revert a couple of these changes. You can delete the
portfolio, our custom portfolio, and then revert this back to the insight weighted
portfolio construction model. That's good. Now we're back to the point where
we have an insight weighted portfolio construction model, and we have this
immediate execution model. So let's do the same thing we were doing here and go
take a look at the immediate execution code. That's all open source here. For this
one actually it is open source, but it's done in C# just for speed.
So you can actually find that.
There you go the algorithm. And so we can just copy this guy, and create a new execution
model in our algorithm. Okay hopefully this is a better track and will keep us
from needing to write some really ugly code.
We're figuring this out on the fly though, so let's see.
We'll just call this the slow execution model.
So the execution models are delivered targets. These targets are what the
portfolio construction model would like you to execute, and then it's up to the
execution model to know and do the actual filling of the the targets that
were given to it. So you can do whatever sort of logic you need.
We have helper collections here like this one, so a portfolio target
collection which is just a helper to hold the collection of those those
targets from the portfolio construction model.
So when targets come in here it can add them to this collection, and then it can
do things like tell you if you're trading in the right order. For
example you might want to sell some shares if we buy others so that you have
enough buying power to place the trades, and that's all handled for you in
these helper methods like portfolio target collection.
Here again this is another helper method, order sizing. You
can get the unordered quantity, so if you pass in the algorithm with this
portfolio in the target that you're trying to execute, it will go and do the
math for you to figure out based on the orders which are open how much of the
target have we got left to fill. We can actually cheat a little bit here, we know
that this is being called once a month, and so we can sort of use that for now
to get this bootstrapped, and see here we're saying we just get the unordered
quantity, and then we place a market order directly for that stock.
What we might want to do instead is simply let's say divide this quantity by
10, and then fill it slowly over time. So one thing that I'm not sure about yet is
this is a daily resolution algorithm. This might be filled over 10 days, or it
might be filled over 10 method calls, and I'm not sure whether or not this
method gets called every day, or whether it gets called every rebalance so we'll
figure that out quickly and then we'll come back and change the code. At the
moment we'll just divide it by 10 so that it fills slowly, and so that we can see
the change in the orders that have been created. Then we can debug what it's
doing exactly. To get a benchmark case because we were making a change in the
execution model let's actually set the immediate execution
model to get our benchmark so we know what we're looking at. Then we can
compare our new execution model to that benchmark.
Okay great.
So we have our benchmark here, we can see a couple of things say here February
the first trade that came in was 126 we sold the bonds, and that's filled
immediately. So let's tweaked it to our execution model.
And just a hunch we'll probably see it fill over the next ten days. So we
will see a slow fill in the the first trade as well the large one, and we might
see a spike in the fees. Wow.
So previous fees rebalancing once a month for about $500. We're up to
$8,000 here. Obviously placing a whole bunch of small trades is going to cost
you a lot of money, so we need to make sure that we're rebalancing every month
and not just causing an increase in trading.
So we need to adjust how that execution model is filling.
You can see the dates here, 2013 August 9th, 10th, 13th, 14th, 15th,
so the hypothesis that the code was running every single day and updating the
execution model is correct. We need to make sure that we do this execution
every month and not just every single day otherwise we're right back to our
daily rebalancing. The core of the traunch rebalancing was that we would take 1/12
of the portfolio and rebalance that. So with the targets that come in these
equate to 100% of the portfolio, and so by dividing it by 10 or 12 here we're
trying to adjust it to to be 1/12 of the portfolio's rebalance every month.
So we can change this slightly so we get the new set of targets at the beginning of
the month. We then allow it to execute a new traunch of the of the rebalancing.
So we'll do the same simple month logic here
if the month is -1 you want to trigger.
And then make sure to save the month.
And return.
And then otherwise if this is a normal rebalancing we'll do the same thing.
if month equal to.. so I've just
made place orders up. We'll create the method in a minute, but it's just doing
the same thing that, we want to do these executions relatively slowly every month,
but start rebalance a fraction of the portfolio.
So let's come to that now.
So we'll come through, this is the execution code which is
called every day, and every time the month changes we'll recalculate the
traunch to rebalance and allow some market orders to go through and rebalance
their traunch.
Alright this looks good, so every month now is going to be getting
the orders, the targets that it needs to fill by the margin impact. So what that
means is it will sell the the ones which need to be reduced first so that
we can free up the buying power. Then we'll get the quantity we need to trade
to hit the targeted rebalance, and then divide that at the
moment by 12 to convert it into a sort of monthly rebalancing, and then send off
the market order for that symbol. This one here is just tidy up, it's just
saying to clear out the targets collection if we've fully fulfilled that
target. There is little differences here which will make a slightly inaccurate,
and I'm not sure if it matters. So for example every month this quantity is
going to be exponentially decaying. There will always be a little fraction that
isn't being rebalanced, so in an ideal world you would literally do 1/12 of the
quantity, and we wouldn't need this. But this way it's appreciating that the
markets probably not going to move in the same direction forever and that
you're going to have changes in what this quantity is requesting.
We'll come back to that maybe we can make that more accurate slightly later.
So let's try this.
And execute.
There is one catch with what we've written, too. First we need to pass
in the algorithm here, and then here if you notice even on the first month this
is only going to be placing one twelfth of the trades that needs to do which
isn't right. We need to, on the first month we need to make the full position
size so that we can compare apples-to-apples, so let's make this
a factor here that we pass in, and we can use that factor in the division.
So here this is divided by one for the first month and then for the subsequent
months we'll do one divided by twelve.
Let's see how this goes.
I'm just going to rename this one here "benchmark". This
benchmark was our rebalancing every single month the entire portfolio, so
we're trying to beat this one. Alright let's see how we go.
Wow, it's smoother than I thought.
Okay good, so we have adjusted the factor that we're using to
rebalance. The first month will rebalance the entire portfolio.
After that we'll only do 1/12 of the portfolio for every 1/12 of the
requested rebalance every time. So here this factor is being passed in to scale
the orders down, and so if we have a look here. Wow 6 trades,
so we've seen relatively low fees and a Sharpe ratio of 1.0, and here we
go back to the beginning you can see as expected we did a massive rebalance on
the 1st of January. Yeah the trades don't look as expected, so let's dig into
this see if we can figure out why. This is our benchmark, every month, and here
was the the target rebalance was supposed to sell SHY and buy SPY, and the
quantities here are relatively small, and then our current backtest it looks like
it's not respecting that at all it's actually increasing the leverage
which is very strange. So let's dig in to that. Presumably this is something
about our execution model and not filling all of its trade.
Well for starters we can see that from the trades that it's processing on February
1st, February 3rd, February 4th so it's not respecting the month rebalancing. That's
number one. That should be an easy one to spot, let's find that, here we go.
If the month isn't equal to the algorithm time month we're placing the
trades and we're not actually resetting our month clock. So now we reset the
month clock we should absolutely be rebalancing once a month. We should be
filling the trades once a month I mean. So let's replace that one. We need to
figure out why the portfolio targets that are being passed in are so huge.
Wait for the trades to finish.
Looks like it might be compounding. Might be some
sort of effect of the portfolio targets growing each month. Let's experiment with
this here. We'll eventually go look at this code, but for now let's experiment by
only adding the targets when the month changes. We don't really care about the
the interim targets, or what I guess is happening is there's 22 trading days in a
month, and the target rebalance here for the first one was 126, so 126 times 22.
It's on that order of magnitude anyway it looks like it's compounding the
rebalance target, so let's just only add the targets to our collection when we
want to actually do the rebalance.
I always like to look up the classes and see how they
work, so you can pretty much find any class of LEAN just
by going to LEAN and looking at search this repository. We've got the test there,
we can look here, and we can find the actual class. There you go. Portfolio target
collection. And so the key thing is here don't get scared off because it's C# it's
just another piece of code, and then you can see here we're adding the portfolio
targets, we're setting the targets for that symbol, so they shouldn't be accruing.
Adding range, we set all the targets for that symbol
We're clearing fulfilled here, this is the code we're calling at the end.
Cool, so look at the actual holdings of that security, and then see whether to remove
that target from the collection.
A lot of other boilerplate code for the dictionary.
Okay
So when we do this add range here, we're overwriting any previous targets.
It should be fairly safe. We can actually leave that here as it was before.
Then we can see here that if the month changes we're going to do our place order routine.
Maybe something here about getting the unordered quantity because this is what
gives us the quantity, and then we come down here to see the quantity traded. So
maybe let's see if we can understand how get unordered quantity works.
So, looking up the get unordered quantity, the very last one here is the order sizing,
and the method we're calling as get unordered quantity.
We can find that one here.
It's relatively simple. It's just the target minus the holdings and rounding
it down to the lot size, so it shouldn't be skewing there. Ah there we go.
Just a simple error. Here we're doing divide by factor, so we just need to do
multiply by the factor because otherwise we're going to be scaling up
our quantity. So let's see how that goes.
What we would expect is 1/12 of this to be
the first order in February so roughly 13 shares, 12 or 13 shares.
Let's see where that is.
Our fees are right about where they were before, so we're seeing slight reduction
in fees, and here on the first of February. Oh sorry, jump to the first one.
Okay so here on the first of February 2003
you see about 10 shares filled, and then five SPY. So we jump to our benchmark we
can confirm yeah it's roughly 1/12 and then roughly 1/12 so looks like we are
filling and rebalancing slower than we were before as we'd hoped. So the
thesis here was really that we would for example in the period of 2009 where you
have a very volatile dip and then a very volatile rise that we could see a more
efficient rebalance. So if we can jump to 2009 about halfway.
Here
from yeah, it looks like we've reduced the positions that we're changing
we can compare that to the numbers from 2009 from our benchmark.
So from here to here, this is our test case.
See on March 2nd 2009 we increased our
position of SPY by 500, and then immediately
decreased that to 300. So then over this
period doing the same thing we can see that we increased it by 200 and then
reduced it by 123. So it is slowing, oh sorry it's the other way around.
Oh no there you go, so see here it's SPY, so we increased it by 200, and then we
went on to increase it again by 146. So because it had the time to do the
rebalancing it didn't immediately flip the position over that one month
it was continuing to increase our holdings versus simply just flipping.
Hopefully that's actually reducing the churn and maintaining a little bit of
momentum in those rebalancings.
Let's see how that does in terms of performance.
So we can see the overall trading is compared to the benchmark about the same roughly,
about the same amount of trading. Our drawdown on the benchmark was 35%.
Our drawdown was 32% with our new rebalancing. Just in case it
wasn't clear before the benchmark here I'm using as a monthly rebalance of
everything, versus a monthly traunch rebalance, and so we can see here
the Sharpe ratio is 0.615 versus 0.595
So there is a slight improvement in the Sharpe ratio by doing this traunch
rebalancing. Just for fun let's see if instead of
doing 1/12 let's just slow it down say a third, and see how it goes.
Overall it's about the same fees, same trading, drawdown slightly
increased, Sharpe ratio's decreased, and let's just confirm it's
operating as we expect. We can see here instead of the 10 that was placing
before, now we've jumped up to shuffling 40 and 21 which is
roughly a third of the benchmark which is doing 113 on this first trade.
So you can see that here. 130 versus 63 and on our new one with our factors
you can see it's effectively rebalancing about 1/3 of the portfolio each month.
So that's good, that's a good framework now we can use this to experiment and so
the overall thesis about whether traunch rebalancing
is more effective than a simple full portfolio rebalancing every month seems
to hold up. We saw a reduction in drawdown and a increase in the Sharpe
ratio, so that was kind of the point to test this thesis and see how it went, and
I'm glad that we saw a positive result, and now we have this scaffolding where
we can test portfolio rebalancing and traunch rebalancing in a relatively easy
way just by changing a factor on the algorithm. So I think that concludes this
video. Thank you for watching, and we're going to try and continue this series of
investigating algorithms about the market and about things we're seeing in
the markets every week. So tune in if you've got ideas of current events that
you would like to be covered please let me know in the comments, and yeah look
forward to chatting with you next week. Cheers.