From API doc for Backtester.Orders, this "returns a List that contains Transaction instances that represent the orders, or signals, that need to be placed for the Strategy at the next market session.". I noticed that this returns all possible signals regardless of the value for "Max Entry Signals". To repro use the following OneNight strategy and set a small number for Max Entry Signals and check the debug output, it's not the same as the produced signals for the next day on the Signals tab.
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using finantic.Indicators; namespace WealthScript7 { public class MyStrategy : UserStrategyBase { MP movingPercentile; public override void Initialize(BarHistory bars) { TR tr = new TR(bars); movingPercentile = new MP(tr, lookback: 100, percentile:75); } public override void Execute(BarHistory bars, int idx) { foreach (var pos in OpenPositions) ClosePosition(pos, OrderType.Market); double mpfactor = 0.7; double limit = bars.Close[idx] - movingPercentile[idx] * mpfactor; PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, limit); } public override void BacktestComplete() { base.BacktestComplete(); foreach(Transaction t in Backtester.Orders) { WriteToDebugLog($"{t.Symbol}"); } } } }
Rename
True, the maximum signal processing occurs after this point in the backtest run. I'm not sure I'd call it a bug but it's good to know the sequence here. Is there something you specially wanted to do in code with the maximum signals under consideration?
Thanks Glitch. I have a utility method I call in BacktestComplete to export signals of each day to a file and use that as historical backup and also use it to match positions on my broker account with my own script (something related to this https://www.wealth-lab.com/Discussion/Add-Trading-Preference-to-exit-position-based-on-executed-order-size-12192).
Is there a way to only return exactly the same signal list as on the Signals tab?
Is there a way to only return exactly the same signal list as on the Signals tab?
QUOTE:
Is there a way to only return exactly the same signal list as on the Signals tab?
I'd also be interested in the answer to that question. I use max. 4 buy signals to publish to GitHub (JSON format) via my own RepositoryPublisher class in In BacktestComplete().
CODE:
private string BuildSignalsJson() { var sb = new StringBuilder(); sb.AppendLine("["); bool isFirst = true; //foreach (Transaction order in _backtester.Orders.OrderByDescending(o => SafeGetDouble(() => o.Weight)).Take(4)) foreach (Transaction order in _backtester.Orders.OrderByDescending(o => SafeGetDouble(() => o.Weight))) { if (!isFirst) sb.AppendLine(","); sb.Append(" {"); sb.Append("\"symbol\":\"").Append(EscapeJson(SafeGetString(() => order.Bars.Symbol))).Append("\","); sb.Append("\"action\":\"").Append(EscapeJson(order.TransactionType.ToString().ToUpperInvariant())).Append("\","); sb.Append("\"signalDate\":\"").Append(EscapeJson(SafeGetString(() => order.EntryDate.ToShortDateString()))).Append("\","); sb.Append("\"entryPrice\":").Append(ToJsonNullableNumber(SafeGetNullableDouble(() => order.OrderPrice))).Append(","); sb.Append("\"stopPrice\":null,"); sb.Append("\"targetPrice\":null,"); sb.Append("\"positionSizePercent\":null,"); sb.Append("\"signalName\":\"").Append(EscapeJson(SafeGetString(() => order.SignalName))).Append("\","); sb.Append("\"orderType\":\"").Append(EscapeJson(order.OrderType.ToString())).Append("\""); sb.Append("\"signalStatus\":\"").Append(EscapeJson(order.SignalStatus.ToString())).Append("\""); sb.Append("\"weigth\":").Append(ToJsonNullableNumber(SafeGetNullableDouble(() => order.Weight))).Append(","); sb.Append(" }"); isFirst = false; } sb.AppendLine(); sb.AppendLine("]"); return sb.ToString(); }
Add this method or use the contents in an existing BacktestComplete() method to prune the Signals to the number you selected for Max Entry Signals so that you can process only those in the Strategy code.
CODE:
using System.Linq; // add to usings public override void BacktestComplete() { // Prune signals per the Max Signals sizer setting PositionSize ps = Backtester.PositionSize; int maxSignals = ps.MaxSignalsPerBar; if (maxSignals == 0) return; WriteToDebugLog("Backtester.Orders count = " + Backtester.Orders.Count); WriteToDebugLog("maxSignals = " + maxSignals); List<Transaction> allowedEntries = Backtester.Orders.Where(x => x.IsEntry).OrderBy(w => w.Weight).TakeLast(maxSignals).ToList(); for (int n = Backtester.Orders.Count - 1; n >= 0; n--) { Transaction t = Backtester.Orders[n]; if (!allowedEntries.Contains(t)) Backtester.Orders.Remove(t); } }
Your Response
Post
Edit Post
Login is required