I have a weights vector representing the portfolio target hourly. The weights vector also includes the ratio of the cash. The absolute sum of the weight vector is the leverage. I am currently using setHoldings method for rebalancing according to that weight vector. However, I couldn't figure out how the cash amount can be considered for rebalancing.
assets = ['AUDUSD', 'EURUSD', 'GBPUSD', 'NZDUSD', 'USDCAD', 'USDCHF', 'USDJPY', 'USDNOK', 'USDSEK', 'USDSGD']
weights = np.array([0.21934296190738678, 0.07689524441957474, 0.02108154632151127, -0.01785222627222538, -0.04997013136744499, -0.08549412339925766, 0.09435564279556274, 0.10972453653812408, -0.08650565147399902, -0.08091041445732117, 0.14116396009922028])
for i, asset in enumerate(assets): self.SetHoldings(asset, weights[i])
Here, if I just use the setHoldings function on the assets without specifying the cash amount. It wouldn't now which leverage to employ for the remaining positions as they wouldn't sum up to the leverage amount. I also did not understand what the boolean liquidateExistingHoldings parameter is for since that if the setHoldings called with a smaller weight wouldn't the possition difference already be liquidated, without setting the liquidateExistingHoldings? Why would someone want to liquidate the whole position beforehand as that would result in unnecessary comission?
Please also advise me on how I can perform this rebalancing hourly rather than each time the onData method is called?
Jack Simonson
Hi Kamer,
To answer your last question first, you can perform rebalancing code at defined time intervals by using a Scheduled Event, and you can view an example of this here.
Regarding the SetHoldings method, SetHoldings tells your algorithm to purchase however many shares of an asset needed to ensure your portfolio value is a given percentage of the total (i.e., self.SetHolding('SPY', -0.5) will tell the algorithm to short 'SPY' as many shares as necessary to make up 50% of the portfolio value). The LiquidateExistingHoldings parameter would be set to True if you are hoping to do a whole rebalance (i.e., clear all positions before placing any new orders), otherwise SetHoldings would only place orders based on how much cash + margin is available if the existing positions remain intact. If there is an issue with insufficient margin, then the algorithm manager will take care of this error and won't try to place an order. Checking margin requirements and understanding the portfolio value can be done using the Securities and Portfolio objects and Order Tickers, which you can find information about here and here.
Kamer Ali Yüksel
Dear Jack, first of all, thank you for your responses to this and other threads, they are being super helpful. I understand now Scheduled Events. However, I guess that won't be necessary for now, as my rebalancing frequency is equal to the resolution of assets and it seems to be working correclty on that aspect (it only places orders hourly now as I desired).
Regarding SetHoldings, this is not at all how I imagined that it works. What I want to do is basically if a position is 50% of the portfolio value, and I need to set it to 40%. It should make an order of -10%. to achieve that.. I am unable to set the parameter LiquidateExistingHoldings to True because in fact; I am hourly changing 2.5% of the portfolio and if the positions are liquidated to do that iterative change, it performs terribly due to unnecessary transaction cost spenditure.
Nevertheless, I also decided to use CalculateOrderQuantity and place LimitOrders to be more profitable than MarketOrders. This is how I am currently doing this but I understand now that this is not sufficient as I probably need to substract the quantity of the existing position from the target quantitiy that is returned by CalculateOrderQuantity. I would be glad if you can help me on how to do that. Note: I previously assumed that such function would return the order quantity required to reach given target portfolio ratio, which doesn't seem to be the case according to your explanation.
    for i, asset in enumerate(assets):
      ratio = weights[i] if asset[-3:] == 'USD' else (-1.0*weights[i])
      #self.SetHoldings(asset, ratio)
      self.Transactions.CancelOpenOrders(asset)
      oq = self.CalculateOrderQuantity(asset, ratio) #Here I probably need to substract the existing position.
      lp = self.Securities[asset].AskPrice * stdarr[i]
      if oq > 0: lp = self.Securities[asset].BidPrice / stdarr[i]
      if oq != 0: self.LimitOrder(asset, oq, lp)
Â
Â
Kamer Ali Yüksel
I have tried to change it as follows, but the previous one were making much more sense in terms of results.
      oq = self.CalculateOrderQuantity(asset, ratio)
      oq -= self.Portfolio[asset].Quantity
Jack Simonson
If you want to adjust holdings from 50% to 40% of your portfolio, all you need to do is call self.SetHoldings(symbol, 0.4) and it will sell off whatever holdings you have in symbol so that your remaining holdings are 40% of the total. However, if you want to use CalculatOrderQuantity and Limit Orders instead, you can find your existing position quantity using self.Portfolio[symbol].Quantity. The Portfolio and Securities objects contain a lot of useful information for these types of calculations and you can read more about them here.
Kamer Ali Yüksel
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!