using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; using WealthLab.PosSizers;namespace WealthLab.Strategies { public class RebalanceStrategy : WealthScript { ///////////////////////////////// // config ///////////////////////////////// bool debugOut = true; string entry1symbol = "Selected Symbol"; string entry2symbol = "IEF"; string entry3symbol = "GLD"; int numEntries = 3; ///////////////////////////////// StrategyParameter entry1portion; StrategyParameter entry2portion; StrategyParameter entry3portion; StrategyParameter holdingPeriod; Tuple<string, double>[] symInfos; public RebalanceStrategy() { entry1portion = CreateParameter(entry1symbol + " portfolio percentage", 30, 0, 100, 5); entry2portion = CreateParameter(entry2symbol + " portfolio percentage", 30, 0, 100, 5); entry3portion = CreateParameter(entry3symbol + " portfolio percentage", 30, 0, 100, 5); holdingPeriod = CreateParameter("holding period", 60, 5, 200, 5); symInfos = new Tuple<string, double>[numEntries]; MS123.PosSizers.BalancingPosSizer.SymInfos = symInfos; } private void OnLog(object sender, MS123.PosSizers.SizerMessageEventArgs args) { PrintDebug(args.Message); } protected override void Execute() { if (debugOut) { ClearDebug(); MS123.PosSizers.BalancingPosSizer.ResetLog(); MS123.PosSizers.BalancingPosSizer.LogMessage += OnLog; } // validation double total = 0; total += entry1portion.Value; total += entry2portion.Value; total += entry3portion.Value; if(total > 100) { if (debugOut) PrintDebug("Bailing out due to total percentage of holdings adding up to more than 100%, total=" + total); return; } entry1symbol = Bars.Symbol; Bars entry1bars = Bars; Bars entry2bars = GetExternalSymbol(entry2symbol, true); Bars entry3bars = GetExternalSymbol(entry3symbol, true); ChartPane pane0 = null; ChartPane pane1 = null; symInfos[0] = new Tuple<string, double>(entry1symbol,entry1portion.Value/100.0); symInfos[1] = new Tuple<string, double>(entry2symbol,entry2portion.Value/100.0); symInfos[2] = new Tuple<string, double>(entry3symbol,entry3portion.Value/100.0); pane0 = CreatePane(75, true, true); PlotSeries(pane0, entry2bars.Close, Color.BurlyWood, LineStyle.Solid, 2); pane1 = CreatePane(75, true, true); PlotSeries(pane1, entry3bars.Close, Color.BurlyWood, LineStyle.Solid, 2); int holding = 0; for (int bar = 0; bar < Bars.Count; bar++) { if(0 == holding) { if(entry1bars.FirstActualBar <= bar) { SetContext(symInfos[0].Item1,true); BuyAtMarket(bar + 1, symInfos[0].Item1 + " buy"); if (debugOut) PrintDebug(symInfos[0].Item1 + " Bought on " + Bars.Date[bar + 1]); } if(entry2bars.FirstActualBar <= bar) { SetContext(symInfos[1].Item1,true); BuyAtMarket(bar + 1, symInfos[1].Item1 + " buy"); if (debugOut) PrintDebug(symInfos[1].Item1 + " Bought on " + Bars.Date[bar + 1]); } if(entry3bars.FirstActualBar <= bar) { SetContext(symInfos[2].Item1,true); BuyAtMarket(bar + 1, symInfos[2].Item1 + " buy"); if (debugOut) PrintDebug(symInfos[2].Item1 + " Bought on " + Bars.Date[bar + 1]); } holding++; } else if(holding >= holdingPeriod.ValueInt) { foreach(Position p in Positions) { if(p.Active) { SellAtMarket(bar + 1, p, p.Symbol + " sell"); if (debugOut) PrintDebug(p.Symbol + " Sold on " + Bars.Date[bar + 1] + ", profit = " + p.NetProfitAsOfBarPercent(bar + 1)); } } holding = 0; } else holding++; } } } }