ww58
- ago
I want to explain using the example of the One Percent a Week Strategy. On Friday, there was a situation where a buy order was executed, but according to the strategy code, the position should have been closed on Friday at market close. That’s exactly how it worked in the backtest. I noticed that in reality, it didn’t.

In the strategy monitor, I had At-Close Signaling disabled. I enabled it, i guess this feature was designed for exactly such situations. But it doesn’t work as expected.

When I enable it, my Next Run changes to 3:59:00 PM (60 seconds before close as specified), even though it should be the set run time. And even if I run the strategy manually, no signals are generated. With it disabled, everything works fine.
0
517
Solved
17 Replies

Reply

Bookmark

Sort
Cone8
 ( 20.40% )
- ago
#1
The public versions of the "One Percent" strategy are not programmed to work with At-Close Signaling. The strategy already "knows" on Thursday that it will exit any position on Friday at the Close.

If the position was open on Thursday, you'd have to cancel the Sell at Limit order and place the MOC at the end of the day on Friday (before 3:55 PM for a MOC order) manually. Alternatively, sell At Market some seconds before the close.

Maybe Glitch can help you with an automated version of the program that would work for At-Close Signaling.
0
Cone8
 ( 20.40% )
- ago
#2
Well heck, since you made me think about it, here's my shot at it. Depending on which version of the strategy you're using, you'll have exit/entry logic something like this...

CODE:
         if (HasOpenPosition(bars, PositionType.Long))          {             double target = LastOpenPosition.EntryPrice;             if (LastOpenPosition.ProfitPctAsOf(idx) > -0.5)                target = target * 1.01;                          Backtester.CancelationCode = 642;                 PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, target);                       Backtester.CancelationCode = 642;             if (idx < bars.Count - 1)             {                if (NextBarIsLastDayOfWeek)                   PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);             }             else             {                //last bar: if today is the last trading day of the week, signal MOC for the open position                if (bars.TomorrowIsLastTradingDayOfWeek(idx))                   PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);             }          }          else          {             if (!Double.IsNaN(mondayOpen) && !tradedThisWeek)             {                double mult = 0.99;                PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, mondayOpen * mult);                if (NextBarIsLastDayOfWeek)                {                   Backtester.CancelationCode = 642;                   PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);                }             }          }


.. which can be simplified to this -
CODE:
if (HasOpenPosition(bars, PositionType.Long))          {             double target = LastOpenPosition.EntryPrice;             if (LastOpenPosition.ProfitPctAsOf(idx) > -0.5)                target = target * 1.01;                          Backtester.CancelationCode = 642;                 PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, target);                       Backtester.CancelationCode = 642;             //last bar: if today is the last trading day of the week, signal MOC for the open position             if (bars.TomorrowIsLastTradingDayOfWeek(idx))                PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);          }          else          {             if (!Double.IsNaN(mondayOpen) && !tradedThisWeek)             {                double mult = 0.99;                PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, mondayOpen * mult);                if (bars.TomorrowIsLastTradingDayOfWeek(idx))                {                   Backtester.CancelationCode = 642;                   // here's a same-bar order if the position is entered on Friday                   PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);                }             }          }

After watching Glitch's video (https://www.youtube.com/watch?v=Z39A55OEudM) for the nth time, I think I've got my brain wrapped around the indexing...

It all comes down to this:
The trick is to place the AtClose order on the *penultimate* bar when processing Friday's partial bar with At-Close Signaling. Assuming the edit to the strategy above, *normally* this should work for the One Percent system because on Thursday's bar, the strategy places the MarketClose order.

But here's the kicker - this note in the user guide:
% Important!% At-Close Signaling is always based on the hypothetical backtest and does not use Live Positions even when Use Live Position is enabled. To exit a broker position with the At-Close Signaling feature, the backtest must have an active (or NSF) Position on the last daily bar.

Last week, the One Percent strategy (the original, not GuyRFleury's version) entered the trade on Friday. Therefore the strategy didn't have a position on Thursday to Sell MOC on Friday. For this special case, I don't think there's a way to make it work when the entry is on the same bar. Glitch?
0
ww58
- ago
#3
QUOTE:
The public versions of the "One Percent" strategy are not programmed to work with At-Close Signaling.
I am using Patreon version.

QUOTE:
For this special case, I don't think there's a way to make it work when the entry is on the same bar.

I assume that the extra At-Close run is meant exactly for such cases, at least that’s how I understood this functionality. In my case, it looks like the strategy monitor doesn’t add an extra run but replaces the current one. As for this particular strategy, removing Friday entries doesn’t really affect the overall profit much. Let’s see what Glitch says.
0
Glitch8
 ( 9.81% )
- ago
#4
I'll run it in the SM this Friday and report back.
0
Cone8
 ( 20.40% )
- ago
#5
I just tested it with the script below (after manipulating the Market hours for TQQQ) with and without entering on the same bar, and it worked fine. Since the backtest gets the partial bar it's able to determine that the entry for "today" put on a position, so it's able to process the MOC order for that position. The code is similar to the way "One Percent" enters and exits at MOC.

Test Script assumes today is Wedesday for an exit At Close today.
CODE:
using System; using WealthLab.Backtest; using WealthLab.Core; namespace WealthScript9 { public class AtCloseSignalingTest : UserStrategyBase {       Parameter _sameday;       public AtCloseSignalingTest()       {          _sameday = AddParameter("Same Day Trade = 1", ParameterType.Int32, 0, 0, 1);       }        public override void Initialize(BarHistory bars) {          StartIndex = 0;    } public override void Execute(BarHistory bars, int idx) {       if (!HasOpenPosition(bars, PositionType.Long)) {             DateTime nextTradingDay = bars.GetNextTradingDate(bars.DateTimes[idx]);             if (_sameday.AsInt != 1)             {                // buy on Monday                if (nextTradingDay.DayOfWeek < bars.DateTimes[idx].DayOfWeek)                {                   Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                }             }             else             {                // same day trade (assumes last complete bar was Tuesday_                if (TomorrowIsWednesday(bars, idx))                {                   Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                   PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);                }             }             } else // Sell on Thursday close {                         Position p = LastPosition;                         if (TomorrowIsWednesday(bars, idx))                ClosePosition(p, OrderType.MarketClose); } }       bool TomorrowIsWednesday(BarHistory bars, int bar)       {          DateTime tomorrow = bars.DateTimes[bar].AddDays(1);          return tomorrow.DayOfWeek == DayOfWeek.Wednesday;       }       } }

Bonus!
Run this strategy (Parameter = 0) with 100% equity sizing on TQQQ since 2010 to buy on Monday and sell Wednesday at the close. You get approximately the same return as the original "One Percent" system.
1
ww58
- ago
#6
The logic here is the same as in the Patreon version, but it seems my issue is specifically with the strategy monitor. I set any strategy for any time - it doesn’t matter. For example, right now it’s 11 AM EST, I set it for 11:30 AM with At-Close Signaling at 60. But then my NextRun is set to 3:59 PM instead of 11:30 AM.

As for this strategy, to avoid confusion, I simply removed entries on Fridays.
0
ww58
- ago
#7
At close isn't working for me.
Today's situation. The strategy didn't run at market open, as it should have. This is because the At-close feature is enabled. Even now, if I press Run Now, no signals are generated. If I turn it off, everything works as expected, but this feature is a must for this strategy.
0
Glitch8
 ( 9.81% )
- ago
#8
Are you activating this after the market open? Don't forget you can always just bypass the Strategy Monitor and run it directly from the Strategy window to get the signals.
0
ww58
- ago
#9
No, I activate it before the market opens, as with any other strategy. There is simply a bug: when I activate At-close, the strategy stops running at the specified time and stops generating signals when I click Run now.
0
Glitch8
 ( 9.81% )
- ago
#10
OK, I'll check, but why do you need to Run Now?
0
ww58
- ago
#11
I don't usually use it, but since it didn't start automatically at the scheduled time today, I clicked Run now to place an order for OPPW
0
Glitch8
 ( 9.81% )
- ago
#12
Got it, I'll look at that sequence and make sure it's fixed for next Build.
1
- ago
#13
Wouldn't this address this situation too?

https://www.wealth-lab.com/Discussion/Orders-rejected-12711

0
Cone8
 ( 20.40% )
- ago
#14
@ww5 -
a. If you're not using Build 138 and are scheduling precisely at the market open time, upgrade to Build 138 (or schedule the run to start 1 second before the open).
b. If you're scheduling a run after the opening time, that won't work.

If that doesn't apply, usually when I think there's a problem, it's because:
1. I didn't notice the "AM" or "PM" in the scheduled time.
2. the Market is not correct (bottom left of the Configuration)

Check those. If you don't see a problem with the Configuration, post an image.

fwiw, I use this every day for 3 strategies that run at the open. It works correctly.


1
Best Answer
ww58
- ago
#15
It seems it was a B option. Now, before the market open, I checked again: if I set the time to 9:30:00 AM EST or earlier, then Next Run is 9:30:00, as it should be; if I set it even one second later, then Next Run goes to At-close time, ignoring the usual start. It's just that nowhere was it specified that the launch should not be later than the market opening, and it seems that this was the issue for me.

I will test it today, but theoretically, NextSessionOpen should have time to get the opening price and everything should work. Thank you all.
0
Cone8
 ( 20.40% )
- ago
#16
NextSessionOpen polls for the opening price every 2 seconds for up to 15 seconds. Especially for Nasdaq instruments, you want to hit that immediately after the open. The value is cached, so it will return immediately without polling if you run again later.

Clock Synchronization -
The Strategy Monitor runs based on your machine's clock. Something I've noticed is that Windows Time Sync (which server doesn't seem to matter) tends to be about 1 second behind the market's clock. If that applies to you, it would be better to schedule the run about 1 second earlier - there's a small delay anyway to load the BarHistory and the round-trip request to return.
0
ww58
- ago
#17
Today's example: two hours before the market open, I set it to Run for 9:30:00 AM with At-close. Here is the log
QUOTE:
10/7/2025 09:30:01: Status = Processing
10/7/2025 09:30:03: Ran Strategy on TQQQ: 0 Signals, Run Time=2sec
10/7/2025 09:30:03: NextRun set to 10/8/2025 09:30
10/7/2025 09:30:03: Status = Completed
10/7/2025 09:30:03: Processed all Symbols

I see that there was no signal, although there should be one, so I'm starting it manually
QUOTE:
10/7/2025 09:36:37: Running Now
10/7/2025 09:36:39: Status = Processing
10/7/2025 09:36:40: Ran Strategy on TQQQ: 0 Signals, Run Time=378ms
10/7/2025 09:36:40: NextRun set to 10/8/2025 09:30
10/7/2025 09:36:40: Status = Completed

Still no signal, removing At-Close, running Run Now
QUOTE:
10/7/2025 09:37:09: Running Now
10/7/2025 09:37:09: Status = Processing
10/7/2025 09:37:09: Pass 1 - Requesting updates for 1 symbols...
10/7/2025 09:37:09: Pass 1 - UpdateHistories returned 0 symbols
10/7/2025 09:37:10: Ran Strategy on TQQQ: 1 Signals, Run Time=280ms
10/7/2025 09:37:10: NextRun set to 10/8/2025 09:30
10/7/2025 09:37:10: Status = Completed
This time, the signal is as it should be.
0

Reply

Bookmark

Sort