- ago
I have A / B / C / D / E / F six symbols in Dataset.

All money has gone to buy three (A / B / C) symbols, there are three other (D / E / F) symbols buying signals today,

I have to sell A / B / C symbols first in Execute before buy D / E / F symbols to avoid NSF, What should i do?

Thx
0
1,672
Solved
21 Replies

Reply

Bookmark

Sort
Cone8
 ( 7.27% )
- ago
#1
Not enough information about the buys and sells.

But, if we're talking about market orders, if I'm not mistaken, exits at market will occur first by backtest design. If I am mistaken (don't think so, but possible), you can set the Transaction.Weight for all trades. The highest Weights are executed first.
0
- ago
#2
This strategy buys only one symbol.

Strategy description:

DataSet : two symbols

calculate 5-day return timeseries

select are two symbols maximum value ( return ) on Thursday

buy the symbol with all capital.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using System.Collections.Generic; namespace WealthScript4 {       public class NSF_strategy : UserStrategyBase    {             private static List<BarHistory> Buys = new List<BarHistory>();       TimeSeries _Ts_Rtn;       double _TE_val;              public NSF_strategy()       {          AddParameter(" Window ", ParameterTypes.Int32, 5, 5, 60, 1);       }              public override void Initialize(BarHistory bars)       {          StartIndex = Parameters[0].AsInt;          _Ts_Rtn = new TimeSeries(bars.DateTimes, 0);                    for (int i = StartIndex; i < bars.Count -1; i++)             _Ts_Rtn[i] = (bars.Close[i] - bars.Close[i - StartIndex]) / bars.Close[i - StartIndex];          bars.Cache["Return"] = _Ts_Rtn;          PlotTimeSeries(_Ts_Rtn, "T(5)-T(0)", "ReturnTimeSeries_Pane");       }        public override void PreExecute(DateTime dt, List<BarHistory> participants) {          foreach (BarHistory bh in participants)          {                TimeSeries _TE = (TimeSeries)bh.Cache["Return"];                int idx = GetCurrentIndex(bh);                _TE_val = _TE[idx];                bh.UserData = _TE_val;          }          participants.Sort((a, b) => -a.UserDataAsDouble.CompareTo(b.UserDataAsDouble)); //H to L                    Buys.Clear();          Buys.Add(participants[0]); } public override void Execute(BarHistory bars, int idx)       {          bool _BuyList = Buys.Contains(bars);                    if(((int)bars.GetDate(idx).DayOfWeek).ToString() == "4")          {             if (!_BuyList)             {                if (HasOpenPosition(bars, PositionType.Long))                   ClosePosition(LastPosition, OrderType.Market);             }             else if (_BuyList)             {                if (!HasOpenPosition(bars, PositionType.Long))                {                   var Q = Math.Floor(CurrentEquity * 1 / bars.Close[idx]);                   PlaceTrade(bars, TransactionType.Buy, OrderType.Market).Quantity = Q;                }             }          }       }    } }


Strategy Settings :



problem 1. Why buy two symbols ( See Backtest Results Equity Curve image )



problem 2. Why is NSF produced ( See Backtest Results Metrics Report image )



Thx.
0
Cone8
 ( 7.27% )
- ago
#3
The NSF issue is easy. You're using 100% equity but the Basis Price is "Market Close this Bar". To avoid NSF with 100% sizing:
1. select Basis Price "Market Open Next Bar", OR,
2. reduce the sizing to account for gaps, OR,
3. Use some Margin, like 1.20

I'll have to look more closely at the script to see how you can end up with 2 positions.
1
Cone8
 ( 7.27% )
- ago
#4
I actually can't duplicate the 2-symbol issue with the 2 instruments I tested with (ZS, TTD).

However, your logic requires a DayOfWeek = 4 to execute. That would be a problem if one of the instruments doesn't trade on that day. Check the questionable trades and the data for that week. Maybe there's a day or two missing.
1
- ago
#5
Hi, Cone

QUOTE:

I actually can't duplicate the 2-symbol issue with the 2 instruments I tested with (ZS, TTD).

However, your logic requires a DayOfWeek = 4 to execute. That would be a problem if one of the instruments doesn't trade on that day. Check the questionable trades and the data for that week. Maybe there's a day or two missing.


I use the IsTradingDay function to determine whether the next day is a trading day

but the symbol (SH600196) date 2010/1/8 does not exist in the data

print out IsTradingDay is true, Why?

CODE:
         string Result = string.Format(" {0:20} {1:20} \r\n {2:20} {3:20} \r\n {4:20} {5:20} \r\n {6:20} {7:20} \r\n {8:20} {9:20}"             , " Today = ", bars.GetDate(idx).ToString("yyyy/M/d")             , " Symbol = ", bars.Symbol             , " NextDayIsTrading = ", bars.Market.IsTradingDay(bars.GetDate(idx).AddDays(1))             , " NextDate = ", bars.GetDate(idx).AddDays(1).ToString("yyyy/M/d")             , " NextDateOfWeek = ", ((int)bars.GetDate(idx).AddDays(1).DayOfWeek).ToString());          WriteToDebugLog("----------------------------------");          WriteToDebugLog(Result);




0
- ago
#6
QUOTE:
but the symbol (SH600196) date 2010/1/8 does not exist in the data

print out IsTradingDay is true, Why?

Because as far the U.S. market schedule is concerned, it's a business day. Apparently, your ASCII symbols are assigned the default market (US Stocks) whereas you're trading Chinese markets.

You could create a new market for Chinese stocks in Tools > Markets and Symbols and configure its properties. Then use its Symbols tab to set up a pattern for stocks like SH###### (assuming all your stocks follow this pattern).

Pay attention to entering holidays so that 2010/1/8 would be recognized. If you did everything right, all symbols starting with SH... and having 6 digits will be assigned to the newly defined China market.

Finally, if you know a reliable historical source of holiday dates for the Chinese market, please let us know so we could beef up WL7 with a new market and include the holiday schedule.
1
Best Answer
- ago
#7
QUOTE:
But, if we're talking about market orders, if I'm not mistaken, exits at market will occur first by backtest design.

This thread is a couple of years old and I'm wondering if we have a more definitive answer today. Based on the WL current build, will WL prioritize sell orders before buy orders on the same bar assuming:
1. Market orders for all signals
2. Live trading

This is critical to know when using a quasi-rotation-type strategy with an IRA account where there is limited margin (only allows immediate use of pending cash for new positions). Assuming account cash is near zero, the broker will reject an attempt to open a new position, unless it is preceded by closing a position with an equal or higher cash value.
0
Cone8
 ( 7.27% )
- ago
#8
Market Exits first, Stop/Limit Exits next, then Entries. Always that order.
This isn't a "priority" question. It always happens that way.

If you're trying to immediately use cash from an exit and don't have margin or cash for a new entry, there's always a chance that order will be rejected. NYSE stocks may open late for example, so a MOO exit may be "Active" for several minutes before the first trade on the primary exchange.
0
- ago
#9
Yes, I understand. These trades are happening mid-market hours. Thanks for the confirmation.
0
- ago
#10
@Cone, I have a type of rotation strategy that requires the cash from a Sell signal to finance a Buy signal (with a limited margin account like an IRA). I have this testing with WL Dummy Broker and today it apparently tried to process the Buy before the Sell and failed. I thought this had happened before, which is why I asked my question.



Is this a quirk with the Dummy Broker or is it likely to perform the same way with a live broker?
0
- ago
#11
Error message was cut off in previous image

0
Cone8
 ( 7.27% )
- ago
#12
Same answer as Post #8.

The dummy broker can take several seconds or more to exit a market order, and, sorting the list for items with the same timestamp won't guarantee that you see the sequence that the orders were processed. Market exits are processed before market entries.
0
- ago
#13
Post #8

QUOTE:
Market Exits first, Stop/Limit Exits next, then Entries. Always that order.
This isn't a "priority" question. It always happens that way.

If you're trying to immediately use cash from an exit and don't have margin or cash for a new entry, there's always a chance that order will be rejected.


Today I made Sell / Buy Market trades with my rotation strategy in four Schwab accounts. The Sells were successful, but the Buys were rejected. The reason for all the rejections was a lack of settled cash. (Since all accounts are IRA with Limited Margin. this shouldn't have happened, since there was enough cash + pending cash to cover the Buys.)

I later manually reran the strategies in the SM using Run Now and the Buy trades successfully filled. Since you have already confirmed that the WL default priority is to Sell Market before Buy Market, do you think this was just an issue of the broker requiring a few seconds to get the buying power updated? Would you recommend putting a delay in the code following a PlaceTrade(....Sell....) to avoid this?
0
Cone8
 ( 7.27% )
- ago
#14
🤷‍♂️
It's not possible to add a delay between Buys and Sells on the same bar.
0
- ago
#15
Since this is a daily rotation strategy, and the algorithm generally signals a Sell + Buy on the same bar, the only way I can think to get a Sell and Buy the same day is to set up a second run in the SM at a time later than the first one. The first run might fail the Buy if not enough settled cash, but the second run should fill the Buy.

What do you think?
0
- ago
#16
QUOTE:
to get a Sell and Buy the same day is to set up a second run in the SM at a time later than the first one.

The so called "second run" is not going to know anything about data structures from the first run, so their activities won't rendezvous. You need to setup a dispatcher data structure within a single strategy to have a prayer of making this work. The dispatcher works as the "central monitor" overseeing the two independent activities so there's enough settled cash in reserve for all independent operations.

You're making this into a complex development project. ... kind of a subframework inside a framework.

Personally, I would keep it simple by getting this running across bars first. Then you could leverage the WL framework to coordinate this activity for you. Maybe you could use 30-minute bars for this.
0
- ago
#17
@superticker
I'm not "making" it complex, just trying to simulate what I was previously doing manually with the tools and capabilities that are available. Amazing how complex it can be to automate some things that are conceptually simple to do manually.

You raise a good point that deserves further clarification. The strategy initially checks broker positions and on the second run will pick up the fact that index "ABC" does not have an active derivative position. It should then place a Buy order. At least I believe that's how it will work. Still would get a Buy Rejected error from the broker on the first run, but all is forgotten by the second run where a null position + buy signal should fill a Buy trade.

0
- ago
#18
QUOTE:
The strategy initially checks broker positions and on the second run will pick up the fact that index "ABC" does not have an active derivative position. It should then place a Buy order.

So you are trying to use the Broker as the "monitor" in this design. One of the jobs of the monitor is to verify there's enough settled cash for all activities. So be sure your monitor (or broker) confirms the settled cash level before pulling the trigger.

And if the broker serves as the monitor, then what do you need the "second run" (and strategy) for? Just do it under one strategy with the monitor (or broker) coordinating the settled cash. And yes, that might mean processing Buys out of a List<BarHistory> toBuy list in Execute.

---
If you're using the broker as the monitor in this design, then how is it possible to do backtesting? Your Monitor class (which you would develop) would be around for backtest simulations, but the broker is only present for real-time trading, not backtesting. I must be missing something unless you're saying you don't care about backtesting your strategy. If so, then why use WL in the first place?
0
- ago
#19
QUOTE:
So you are trying to use the Broker as the "monitor" in this design.

That's an interesting way to put it. But the Broker info is only one part of the decision process. There is still whether the position should be active or not.

QUOTE:
And if the broker serves as the monitor, then what do you need the "second run" (and strategy) for? Just do it under one strategy with the monitor (or broker) coordinating the settled cash. And yes, that might mean processing Buys out of a List<BarHistory> toBuy list in Execute.

Well, that's the problem. In the API (at least for Schwab) there does not appear to be a way to get the same cash value that the backroom trading system is using, and possibly loop in code until it is finished updating. The functions available to report available cash are showing sufficient cash is available, and it is, but the Broker does not complete its reconciliation of cash for a short period and rejects the trade because pending cash has not been added to settled cash, even though the API call reports the sum of those as cash. In other words, there is some black-box cash reconciliation being done on the Broker side that is not exposed to WL By the time the strategy is run again, the Broker cash is fully reconciled. This disconnect likely only exists for a fraction of a second.
QUOTE:
If you're using the broker as the monitor in this design, then how is it possible to do backtesting?
Good question. This has an unusual structure for a strategy. I do a lot of the special processing on the last bar, where I switch from a BackestPosition to BrokerPosition.

Addendum
If, for example, WL had a way to check the status of a trade, I could test for rejection and re-place the trade.
0
Cone8
 ( 7.27% )
- ago
#20
QUOTE:
If, for example, WL had a way to check the status of a trade, I could test for rejection and re-place the trade.
When the signals are issued, the strategy is done. This isn't a WealthLab problem, it's a buying power problem that is actually no problem at all in a typical margin account.

fwiw, you can manually select and Place the orders that failed (or were cancelled). It's at least worth a test to see how long you have to wait for Schwab to update the buying power.
1
- ago
#21
QUOTE:
I do a lot of the special processing on the last bar, where I switch from a BackestPosition to BrokerPosition.

Ya, I "override" my strategy manually doing the same thing. And I end up buying positions that slip down (loosing money) later in the day because these overrides are not statistically backtested.

What we both should do (although it's hard to do so psychologically) is trust the statistics and the backtesting. Same old song. :(
0

Reply

Bookmark

Sort