- ago
In WL6, I have a ResyncPort(...) class who's job it is to resync my "real" stock ownership with the WL simulation. It operates only on the off-the-chart bar so its activity is transparent to the Performance Visualizers--an essential requirement.

If a "real portfolio" position is no longer owned by the WL simulation on the last bar, it will automatically sell that position on the off-the-chart bar creating a trading Alert. Since WL won't let one sell a position that's not already owned, a "pseudo buy" is performed on the last bar so the off-the-chart bar can now be sold creating the sell Alert. This procedure has saved me $1000s by alerting me about falling orphaned stock positions that got out-of-sync with WL. It worth its weight in gold!

My question is how to make this work under WL7?

1) The best approach would be to add a TransactionType.GhostSell to the PlaceTrade method, which would allow an "unconditional sell" on the off-the-chart bar even if that position wasn't owned by the WL simulation.

2) Alternatively, allowing a pseudo buy on the last bar of the chart so a sell becomes possible on the on the next (off-the-chart) bar. But how does one tell PlaceTrade to buy on the current (and last) bar, which I can easily do with WL6?
CODE:
WSObj.BuyAtMarket(bar,"Pseudo buy"); //create a sham Buy


3) Install the ResyncPort(...) behavior in the core logic of WL7. It's a killer feature to resync orphaned positions back to the WL simulation. It works both ways for either buying or selling orphaned positions. And the core method has only 25 lines of code (not counting the constructor). I wouldn't trade without it.
0
1,309
Solved
26 Replies

Reply

Bookmark

Sort
- ago
#1
QUOTE:
But how does one tell PlaceTrade to buy on the current (and last) bar, which I can easily do with WL6?

How about:
CODE:
public override void Execute(BarHistory bars, int idx) {          if(idx == bars.DateTimes.Count -1)          {             DrawHeaderText(string.Format("Last bar: {0}, Date: {1}", bars.DateTimes.Count - 1, bars.DateTimes[idx]));             PlaceTrade(bars, TransactionType.Buy, OrderType.Market);          } }
0
Cone8
 ( 24.56% )
- ago
#2
Something like this should work to Alert for an orphan.

CODE:
public override void Execute(BarHistory bars, int idx) { /* Orphan check */ if (!HasOpenPosition(bars, PositionType.Long)) {       if (idx == bars.DateTimes.Count - 2)       {          // your orphan logic here...          DateTime marketDateTomorrow = bars.DateTimes[idx + 1];                   bool foundAnOrphanToExit = true;                       if (foundAnOrphanToExit)           PlaceTrade(bars, TransactionType.Buy, OrderType.Market);       } } else {                //sell the orphan       PlaceTrade(bars, TransactionType.Sell, OrderType.Market);             } }
0
- ago
#3
The solution in Reply# 1 will fail because PlaceTrade is performing the buy operation one bar ahead, which will be on the bars.DateTimes.Count or off-the-chart bar--the same bar we are trying to sell on. Now if you can issue both a Buy and a Sell on the off-the-chart bar on the same Execute(...) iteration (Can you?), it "might" work. (Kind of strange. Is this allowed?)

The method in Reply# 2 is flawed because it's trying to check for an orphan one bar too soon (bars.DateTimes.Count-2, the second to the last bar). It would be buying the position a second time before one really knew it was actually an orphan to begin with. One needs to wait until the last bar (bars.DateTimes.Count-1) on the Chart to determine if it's truely an orphan. Also, if you perform the buy on the second to last bar, the stats for the Performance Visualizers will be affected. The "pseudo buy", if needed, must be performed on the last Chart bar to avoid this.

These are good tries, but they won't quite work. The fundamental problem is WL won't let you sell a position not owned by the simulation without the TransactionType.GhostSell feature (suggestion# 1) and PlaceTrade will always place a "pseudo buy" on the next bar when you need to place it on the current and last bar of the Chart (suggestion# 2). We're in a pickle with the current WL7 design. :(
0
Glitch8
 ( 7.81% )
- ago
#4
I had a hard time following this, but WL7 already issues sell alerts for all “ghost” positions that were not filled by the simulation because of insufficient simulated equity. Because you might have that position in your real world portfolio it was important to issue the sell signals for the “ghost” positions. So it’s possible WL7 already does what you need, turning your pickle into a delicious relish 🙂
0
- ago
#5
@Glitch
This is about the WL simulation successfully selling a position that fails to get sold (like it should) in the real portfolio; therefore, the portfolio gets out of sync with the simulation. It has nothing to do with simulated capital; I strictly use Raw Profit Mode in WL6. (It has more to do with rounding error in some indicators creating orphans or human trader missteps and overrides.)

ResyncPort(...) has a list of "real" portfolio positions it compares with simulated positions owned on the last bar of the Chart. If this doesn't match it takes action on the off-the-chart bar to generate a trading Alert.

1) If the simulation doesn't own a position on the last bar and the real portfolio does, it generates a Buy order on the last Chart bar [u]and[\u] a Sell order for the off-the-chart bar.

2) If the simulation does own a position on the last bar and the real portfolio doesn't, it generates a Buy order for the off-the-chart bar.

Some of the out-of-sync instances are "by intervention". For example, the simulation my say to buy it, but I don't want to. Then on the following day, WL entry code still thinks this now out-of-sync stock is still a good buy, so ResyncPort() steps in to create its own Alert to buy. And maybe I do buy it on the second or third alert.

Some of the positions become orphans because of rounding errors somewhere in the simulation. We have to live with that. And that was the original motivation for creating ResyncPort(). And it has saved me $1000s by flagging orphaned falling stocks I would have otherwise missed in WL6 Raw Profit Mode.

0
Glitch8
 ( 7.81% )
- ago
#6
Ah ok, we have an item in our feature pipeline to implement some portfolio synch functionality!
0
- ago
#7
If you like, I can share the WL6 code I use for the ResyncPort class. If you're interested, I can open a support ticket and post it there. It's fairly simple code. All you need to do in the strategy is replace the IsLastPositionActive with the code shown below.
CODE:
namespace WealthLab.Strategies {    public class MyStrategy : WealthScript    {       private ResyncPort posTrack = new ResyncPort();       protected override void Execute()       {          ...          for (int bar = GetTradingLoopStartBar(30); bar < Bars.Count; bar++)          {             if (posTrack.IsLastPositionActive(bar)) //replaces IsLastPositionActive                if (sellCondition)                {                   //code your exit rules here                   SellAtMarket(bar+1, LastPosition, "Schaff sell");                }                else                if (buyCondition)                {                   //code your entry rules here                   BuyAtMarket(bar+1, "Schaff buy");                }          } //end trading loop       }    } }

What I would suggest is to implement ResyncPort(...) for WL7 and run it as such. Later it can be wrapped into the WL7 core. To implement it in WL7, I'm probably going to need the TransactionType.GhostSell choice added to PlaceTrade to allow a sell on the off-the-chart bar even if a position isn't owned by the simulation.
0
Glitch8
 ( 7.81% )
- ago
#8
Thank you for the code sample. I have a better idea now of what you’re describing. Let me think about this and we’ll definitely incorporate these ideas when it comes time to work on this feature.
0
- ago
#9
I'm sorry if I wasn't originally clear what's happening here. A code example is worth a thousand words.

Basically, ResyncPort() "redirects" WL program flow from buy-code processing to sell-code processing or vice versa for the off-the-chart bar whenever the final position is orphaned.

Now just because there's a redirection does not mean a trade Alert will be generated--that's important. A trade alert is only given if that position also passes the trading condition in the strategy. For example, say the WL simulation owns said position, but the real portfolio doesn't. ResyncPort() will redirect the execution into the buy-condition code, but that strategy's buy condition must still be met before any Alert is ever generated.

So even if I don't buy the position on the first Alert, a second Alert "might" be given on the next bar or several bars down the road **if** the strategy's buy condition is met again.

The smarts--and testing--still lie within the strategy code. ResyncPort is only redirecting the program flow to facilitate re-synchronizing the portfolio to the WL strategy **if** the strategy's trading conditions are still met.

When you see ResyncPort() main method is only 25 lines, you'll want to include it because it's simple to do. Those 25 lines are a little tricky, but I'm happy to share them with you. I've been using them in production for 2 years with great success. And I wouldn't trade without it. So make WL7 support it somehow.
0
- ago
#10
It just occurred to me that the simplest solution to making ResyncPort() work in WL7 is to honor all Sell requests for the off-the-chart bar whether a position is owned or not. (Perhaps WL is already doing that.) Then an "ordinary" TransactionType.Sell on PlaceTrade would work for all off-the-chart bar cases. And ResynPort() could force an off-the-chart sell whenever it needed to.

Naturally, for any sell attempted for any bar on the Chart, that would still throw an error if it wasn't already owned.
0
- ago
#11
From searching this is the resync item that I would be looking for too in order to eliminate manual wealth signals updates and manual sell orders. What feature request is this under for voting purposes?
0
Glitch8
 ( 7.81% )
- ago
#12
WL7 is already working just like Superticker described above.
0
- ago
#13
QUOTE:
WL7 is already working just like Superticker described above.

In order to make ResyncPort() work:

1) WL7 has to have access to your actual portfolio as published by your broker so it can identify what positions need resync'ing to the WL's simulation. Is WL7 now portfolio aware? How does a strategy see the broker's stock positions?

2) WL7 needs to place a sell order on the off-the-chart bar even if the WL simulation thinks it does not own it to perform the portfolio resync'ing. Last time I checked, one couldn't sell a position the simulation didn't already own. Has that now changed for the off-the-chart bar?

I've been using WL6 for live trading currently because WL7 was missing these features. I've shelved porting ResyncPort() to WL7 because of #1 and #2 limitations. I can take another look at porting this routine again to WL7 if the above has been corrected. Has it?

ResyncPort() works great on WL6. I've used it for 3.5 years. I love its ability to resync my portfolio to the WL simulation automatically. It's a great feature and has saved me lots of money by resync'ing orphan positions.
0
- ago
#14
It currently does not resync orphan positions. I have to manually adjust them.
0
- ago
#15
Before ResyncPort() on WL6, I had about 3% orphan positions that I would loose money on. There isn't a foolproof way to prevent some of those. So developing ResyncPort() solved that problem. But I can't completely port it to WL7 for reasons #1 and #2 above. But when I can (#1 and #2 corrected), I will. Then I'll be able to use WL7 for live trading.
0
- ago
#16
Quote from Reply# 25 of https://www.wealth-lab.com/Discussion/Buy-and-sell-on-the-same-date-time-6224
QUOTE:
It's certainly possible to buy and sell on the same bar,

That's true, but with the code below
CODE:
public override void Execute(BarHistory bars, int idx) {          if (idx == bars.Count-1)          {             PlaceTrade(bars, TransactionType.Buy, OrderType.Market);             PlaceTrade(bars, TransactionType.Sell, OrderType.Market);          } }
I only get a Signal for a Buy. In contrast, in the WL6 version of this code, I get a Signal (Alert) for a Sell instead, which is what I need to sell off the orphaned stock position. Now you're going to say, but the WL6 version Buys on "bar" and Sells on "bar+1" (the off-the-Chart bar), and that's true. But there's no way to do that in WL7.

My proposed Feature Request treats this totally differently. It would handle this situation with a single off-the-Chart Sell without a "pseudo Buy" ever being involved, afterall, the "orphaned stock" is already own by the real portfolio.
0
Glitch8
 ( 7.81% )
- ago
#17
I don't know what you mean by "orphaned stock Position".

I'm having trouble understanding the use case here.
0
- ago
#18
QUOTE:
I don't know what you mean by "orphaned stock Position".

Read the original posting in this thread again. We have an orphaned stock position that missed getting sold on the previous day (sometimes by accident, sometimes by design), so the real portfolio is now out of sync with the WL simulation.

The job of ResyncPort(...) is to resync the real portfolio to the simulation by selling that orphaned stock position. Just read the original post again. ResyncPort(...) is embedded in the strategy as shown in Reply# 7. I have a WL7 version of this embed I can post if you like.

This is about damage control or exception handling. In a perfect world, you wouldn't need any of this in the first place. But in practice, there are times (sometimes by intervention) where the real portfolio gets out of sync with the WL simulation. ResyncPort(...) manages this exception handling automatically.
0
- ago
#19
Please post your adjusted WL7 code (I tried but was not able to successfully modify your WL6 code) as currently have to manually sell orphan positions and would prefer my strategy automatically do that.
0
- ago
#20
QUOTE:
Please post your adjusted WL7 code as currently have to manually sell orphan positions and would prefer my strategy automatically do that.

ResyncPort(...) will not currently work under WL7 without a special Feature Request since WL7 won't let it sell an orphaned position. I kind of hinted to that Feature Request in the initial post of this thread. And understand, we are talking about after the fact damage control, and not normal program flow. This is how you would insert it into your WL7 code.
CODE:
namespace WealthScript3 { public class MyStrategy : UserStrategyBase {       ResyncPort posTrack = new ResyncPort();        public MyStrategy() {           posTrack.GetUserStrategyBase(this as UserStrategyBase); } public override void Execute(BarHistory bars, int bar) { if (posTrack.HasOpenPosition(bars, PositionType.Long, bar)) { //code your sell conditions here } else { //code your buy conditions here } } } }

ResyncPort(...) works fine under WL6 because WL6 let's you "pseudo Buy" then Sell to clear the orphaned position, but not WL7. That's the problem.
0
Glitch8
 ( 7.81% )
- ago
#21
WL7 will let you sell an orphaned position. You just need to assign a value to the Transaction Quantity.
0
- ago
#22
QUOTE:
WL7 will let you sell an orphaned position. You just need to assign a value ...

Please post an example of WL7 selling a simulated position it does not already own (which would be the orphaned position of the simulation). I've tried to sell nonexistent WL7 positions (nonexistent to the simulation) without any success so far. And what "value" are we talking about?

There's probably an undocumented trick to doing this. Remember, we are talking about after the fact exception handling, not normal program flow. In a perfect word, ResyncPort(...) wouldn't be unnecessary.
0
Glitch8
 ( 7.81% )
- ago
#23
i already did in a recent thread
0
- ago
#24
If it's the other thread with a Buy in it, that won't work. Post an example with only a Sell without any Buy order. Remember the orphaned position already exists in the portfolio, so we do not want to post a Buy order. We only want to force a Sell order on the off-the-Chart bar. How to I do that?

And when I tried the example you're referring to, I only get a Buy signal for the off-the-Chart bar. I don't want that. I want only a Sell signal without the Buy signal. (I don't actually want buy anything because the orphaned position is already owned.)
0
Glitch8
 ( 7.81% )
- ago
#25
CODE:
using WealthLab.Backtest; using WealthLab.Core; namespace WealthScript1 { public class MyStrategy : UserStrategyBase { //Initialize public override void Initialize(BarHistory bars) { } //Execute public override void Execute(BarHistory bars, int idx) { if (idx == bars.Count - 1) { Transaction t = PlaceTrade(bars, TransactionType.Sell, OrderType.Market); t.Quantity = 123; } } } }
0
Best Answer
- ago
#26
Interesting. I haven't seen that solution before. That above solution appears to work--I've just tried it. And yes, the LastPosition holds the Quantity that failed to sell on one of the previous bars (creating the orphaned position), so it's easy to add the Quantity parameter in there. Now if the orphaned position was originally bought with NSF funds, the LastPosition.Quantity parameter maybe a little off from the orphaned position size in the portfolio. I wonder if the Order manager will make the necessary adjustments?

Let me modify my code and test it for a couple days to be sure it works. It would be nice to get ResyncPort(...) finally running on WL7. Thanks a million.
0

Reply

Bookmark

Sort