This will hopefully plug the last gap remaining in WL8 live trading capability. WL8 already has some support for syncing your Strategy with the underlying broker account, but Sync Live Positons will prevent some complications like orphan positions.
In a live trading context, streaming chart or strategy monitor, when this option is enabled, prior to running the last bar of data, WL8 will delete all existing theoretical positons, and add the positons from the live broker account.
Pros:
- We shouldn't have any more orphan positons or orphan positons sales.
- If the broker failed to sell a position by not being able to fill a limit price, for example, the position will still be there for WL8 to try and exit again.
Cons:
- It won’t be as easy to auto-trade strategies that maintain multiple positions in the same symbol.
- You’re getting the whole position from the broker, so if you want to exclude a part of it you’ll still have to adjust the position size accordingly.
Vote for the request if you like it!
In a live trading context, streaming chart or strategy monitor, when this option is enabled, prior to running the last bar of data, WL8 will delete all existing theoretical positons, and add the positons from the live broker account.
Pros:
- We shouldn't have any more orphan positons or orphan positons sales.
- If the broker failed to sell a position by not being able to fill a limit price, for example, the position will still be there for WL8 to try and exit again.
Cons:
- It won’t be as easy to auto-trade strategies that maintain multiple positions in the same symbol.
- You’re getting the whole position from the broker, so if you want to exclude a part of it you’ll still have to adjust the position size accordingly.
Vote for the request if you like it!
Rename
If we are going to have Live Position available, then maybe we can calculate the Sell Profit Target based on the actual cost
Absolutely!
I just wanted to voice my whole-hearted support for this feature! In live-trading scenarios, I'm constantly running into situations where an order fails for some crazy reason, and I'm always worried about my strategy getting into some busted state where it's incorrectly holding a position that the Strategy Monitor thought it sold long ago.
Being able to use live positions would certainly provide a lot of peace of mind, and for my use cases, none of the Cons are applicable.
Being able to use live positions would certainly provide a lot of peace of mind, and for my use cases, none of the Cons are applicable.
Agree, I'm going to activate this for development!
Hi Mike, Hi Glitch,
I think a very good point is to say: "Be able to use ...". Maybe it can be implemented as an option in the trading settings so that for the users who need to handle the disadvantages they can trade in the current mode.
Personally, I see it exactly like you Mike. Thank you Glitch for this decision.
I think a very good point is to say: "Be able to use ...". Maybe it can be implemented as an option in the trading settings so that for the users who need to handle the disadvantages they can trade in the current mode.
Personally, I see it exactly like you Mike. Thank you Glitch for this decision.
QUOTE:
when this option is enabled, prior to running the last bar of data, WL8 will delete all existing theoretical positions, and add the positions from the live broker account.
Just make sure WL executes the "Sell leg" of the strategy if there's a hanging orphan position that needs to sell, and the "Buy leg" of the strategy if there's a missed position that should have been bought earlier. If there's a
CODE:statement in the code, the above behavior becomes easy to implement because the Sell and Buy leg are clearly defined. If there isn't such a statement, then the user may need to add a pseudo statement to define which sections of the Execute{} code are for Buy and Sell.
HasOpenPosition(bars, PositionType.Long)
I have some code I can email to the development team for doing this, which I've been using for 5 years successfully. The WL6 version works perfectly because it's possible to sell a position on the "current" bar so the Sell leg of the strategy executes immediately. The WL8 version is more confusing because the Sell leg is executed a bar late since PlaceTrade(...) always executes on the next bar so the position remains orphaned for an extra bar. Let me know if you want the code. It's less than 20 lines long in my code library and is a HasOpenPosition(...) replacement.
The only way I can imagine the solution would be to synchronize a Strategy's LastPosition by symbol with the DataSet and BrokerPositions.
Example:
If the Strategy is executing on the Dow 30 DataSet and you have Positions in AAPL and CSCO (both in Dow 30) and also ADSK, BKR, and BBBY (not in the Dow 30), executing GetPositionsAllSymbols() on bars.Count - 1 needs to return AAPL and CSCO - even if the strategy's state on the last bar wouldn't otherwise have open positions for those symbols.
That could be done by injecting new Positions, if required, on the last bar. But that wouldn't work because many strategies need to know the age of a position.
Consequently, I think the solution would be to ignore the last hypothetical exit, if required, for AAPL and CSCO, and let the strategy logic take over normally. For this to work, the strategy will have needed to create a position at least once for the data loaded, which is a reasonable assumption.
Example:
If the Strategy is executing on the Dow 30 DataSet and you have Positions in AAPL and CSCO (both in Dow 30) and also ADSK, BKR, and BBBY (not in the Dow 30), executing GetPositionsAllSymbols() on bars.Count - 1 needs to return AAPL and CSCO - even if the strategy's state on the last bar wouldn't otherwise have open positions for those symbols.
That could be done by injecting new Positions, if required, on the last bar. But that wouldn't work because many strategies need to know the age of a position.
Consequently, I think the solution would be to ignore the last hypothetical exit, if required, for AAPL and CSCO, and let the strategy logic take over normally. For this to work, the strategy will have needed to create a position at least once for the data loaded, which is a reasonable assumption.
It's not that complicated. All you need to do is redirect the HasOpenPosition() in WL8 (IsLastPositionActive() in WL6 below) to the correct Buy or Sell leg of the strategy. The strategy code will automatically handle the rest, which is the beauty of this solution.
I've included the WL6 solution below--which I've been using for five years--because it's easier to follow since it's possible to create a "sham Buy" on the "current" bar (not bar+1 like is normally done in WL6) so there's a simulated position to sell on the next bar (to remove the orphaned position). In WL8, you can't do that, so the code is more confusing.
I've included the WL6 solution below--which I've been using for five years--because it's easier to follow since it's possible to create a "sham Buy" on the "current" bar (not bar+1 like is normally done in WL6) so there's a simulated position to sell on the next bar (to remove the orphaned position). In WL8, you can't do that, so the code is more confusing.
CODE:
namespace WealthLab.Strategies { public class RSDif_Trend : WealthScript { private ResyncPort posTrack = new ResyncPort(); } protected override void Execute() { posTrack.GetWealthScript(this as WealthScript); ... for (int bar = GetTradingLoopStartBar(20); bar < Bars.Count; bar++) { if (posTrack.IsLastPositionActive(bar)) { //Sell code here } else { //Buy code here } } } } namespace Superticker.Components { public class ResyncPort //Resynchronizes the real portfolio to the WL simulation via Alert management { public string[] PortfolioSymbols { get; private set; } //private List<string> symbolsOwned; //open positions in portfolio internal WealthScript WSObj; public ResyncPort() { string wlDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"Fidelity Investments\WealthLabDev\1.0.0.0\Data"); FileInfo SymbolsInputFile = new FileInfo(Path.Combine(wlDataDir, "DataSets", "žž symbols owned.xml")); //Wealth-Lab dataset PortfolioSymbols = ReadXmlDataSet(SymbolsInputFile); //input owned symbols } public void GetWealthScript(WealthScript WSRef) { WSObj = WSRef; //WealthScript object reference } /* public string[] PortfolioSymbols //rtn symbols owned by real portfolio { get { return symbolsOwned.ToArray(); } } */ //Enters Buy code when the real portfolio doesn't own the position even if the simulation does //in order to resynchronize the portfolio with the ownership of the simulation. Likewise, //enters Sell code when the real portfolio owns the postition even if the simulation doesn't //in order to resynchronize the portfolio with the ownership of the simulation. public bool IsLastPositionActive(int bar) { if (bar < WSObj.Bars.Count - 1) //Is this the last bar on the Chart where an Alert maybe generated? return WSObj.IsLastPositionActive; //no, so precede normally else //for processing the last bar on the Chart, which may generate an Alert for the off-the-chart bar //return symbolsOwned.Contains(WSObj.Bars.Symbol); //flag Alerts based on real portfolio ownership { if (WSObj.IsLastPositionActive) //Is the simulation executing its Sell code? return Array.IndexOf(PortfolioSymbols, WSObj.Bars.Symbol) != -1; //yes, so exec Sell code *if* actually owned //return symbolsOwned.Contains(WSObj.Bars.Symbol); //yes, so exec Sell code *if* actually owned else { //no, sumulation is executing its Buy code instead if (Array.IndexOf(PortfolioSymbols, WSObj.Bars.Symbol) != -1) //... so does the portfolio actually owned this symbol? //if (symbolsOwned.Contains(WSObj.Bars.Symbol)) //... so does the portfolio actually owned this symbol? { WSObj.SetPaneBackgroundColor(WSObj.PricePane, bar, Color.Plum); WSObj.BuyAtMarket(bar, "Pseudo buy"); //yes, so create a sham Buy so there's a simulated position to sell return true; //exec Sell code to generate an Alert to close this orphaned portfolio position } else return false; //nothing active and Open, so exec Buy code unconditionally } } } } }
QUOTE:I'm pretty sure this will not be the solution for precisely the reason I mentioned that injecting a position "wouldn't work" [for many strategies] because you don't know the age of the position.
//yes, so create a sham Buy so there's a simulated position to sell
I already implied it is "a solution", but it's certainly not the best - imho. But you and I can jawbone all we want. Glitch will probably come up with something that no one has predicted yet, as he often does.
QUOTE:
I'm pretty sure this will not be the solution for precisely the reason I mentioned that injecting a position "wouldn't work" [for many strategies] because you don't know the age of the position.
I'm saying the age of the position should not matter for synchronizing the portfolio with the simulated strategy. In many cases, I intentionally skip buying a position WL wants to buy only to buy it several bars later. This is a good feature of this approach, not a disadvantage. And I would like to preserve this option. (Perhaps this should be a preference option.)
Moreover, if timing which bar needs to be the entry (and for some short-term strategies it is), then the user should be using a crossover test to get precisely in on that bar. I use inequalities instead of crossovers for entry tests because I'm looking for a particular condition to be satisfied.
Just because it doesn't matter for you, it does matter for many non-superticker strategies. Here are 2 concrete examples -
1. Let's say I want sell at a some limit price after having held the position for 10 bars. Futhermore, the limit price depends on the number of bars the position was active. Imagine after 12 bars the limit price hits, but my account didn't exit. If you inject your "sham buy", the strategy won't know place a limit order because the position's age is either wrong or best case, a very good guess.
2. A good number of strategies have profit targets and stop losses. Assuming you can get the basis price of the position from the broker, you'd be covered, but we can't depend on that. We may need to know the signal bar or some other position property that you can't get with a sham buy.
In both of these cases, if you assume that the position belongs to the last hypothetical entry, and you ignored the hypothetical exit (because the real exit didn't occur) the strategy will be in synch and can generate the proper signals.
Is there something about your sham position solution that can solve either one of these cases?
1. Let's say I want sell at a some limit price after having held the position for 10 bars. Futhermore, the limit price depends on the number of bars the position was active. Imagine after 12 bars the limit price hits, but my account didn't exit. If you inject your "sham buy", the strategy won't know place a limit order because the position's age is either wrong or best case, a very good guess.
2. A good number of strategies have profit targets and stop losses. Assuming you can get the basis price of the position from the broker, you'd be covered, but we can't depend on that. We may need to know the signal bar or some other position property that you can't get with a sham buy.
In both of these cases, if you assume that the position belongs to the last hypothetical entry, and you ignored the hypothetical exit (because the real exit didn't occur) the strategy will be in synch and can generate the proper signals.
Is there something about your sham position solution that can solve either one of these cases?
If there is no hypothetical position but one exists in the broker account, a new position will get injected.
If a hypothetical position exists but it does not exist in the broker account, the hypothetical position will get deleted.
If there is a match, then the hypothetical position can get adjusted.
There will never be a perfect solution, that's why this is an OPTION and will have drawbacks, especially for Strategies that rely on the age of the position, because that information will be lost in the first case.
If a hypothetical position exists but it does not exist in the broker account, the hypothetical position will get deleted.
If there is a match, then the hypothetical position can get adjusted.
There will never be a perfect solution, that's why this is an OPTION and will have drawbacks, especially for Strategies that rely on the age of the position, because that information will be lost in the first case.
QUOTE:
If you inject your "sham buy", the strategy won't know place a limit order because the position's age is either wrong or best case, a very good guess.
The "sham buy" is placed unconditionally in the library code whenever an orphan position exists that should have exited. Oh, I see your point; the sham buy isn't carrying the same entry properties as the original entry position.
My main concern is some strategies are designed for very short-term positions, so timing on the bar becomes an issue and needs to be detected with a crossover test. It's these short-term strategies with crossover entries and exits that concerns me. The crossover conditions may fight the handling of out-of-sync cases by the strategy itself. Perhaps there needs to be "overriding behavior" involved, but then this feature needs to be disabled if necessary. Perhaps the solution for short-term strategies needs to be different for long-term strategies, although that complexity doesn't appeal to me so much.
Let me make this statement. I would like a solution that can Buy (or Sell) late if the opportunity to do so favors it. How you do that is up to you.
QUOTE:yes, but not just age - profit target, stop loss, and probably a few others cases.
especially for Strategies that rely on the age of the position, because that information will be lost in the first case.
How about a compromise?
Inject the position with the entry bar details of the last hypothetical entry.
That's what I meant here:
>>If there is a match, then the hypothetical position can get adjusted.<<
>>If there is a match, then the hypothetical position can get adjusted.<<
I like the planned solution. On the preference to enable this feature, a warning might be included saying this feature is not recommended with strategies that depend on time held by the position or crossover entry and exit conditions where a "specific bar" is targeted.
I would keep it simple for version 1.0 of this feature until some feedback is given. Simple is beautiful even if doesn't handle every case.
I would keep it simple for version 1.0 of this feature until some feedback is given. Simple is beautiful even if doesn't handle every case.
Is it possible we might see an initial version of this feature in the next WL8 release or two? Or is it likely still a ways off? I'm really excited to give it a try.
It’s already developed and is now in testing for build 28.
I'm still having some issues with live trading. I'm getting minute bar data and wondering if there is some delay between the broker and wealth lab.
Gemini 3 has suggested some code to check for a live position even though wealth lab also checks to see if the position is at the broker.
I started looking at this when orders are not completely filled within one bar and the position is filled over a couple of bars.
Any ideas on the best approach to get wealthlab to process exactly what is in my broker account?
The reason you see stops and limits is that PlotStopsAndLimits visualizes the Backtester's "Theoretical" Reality, not your Broker's Actual Reality.
Here is the breakdown of why this happens and how to stop it.
1. The Cause: The "Ghost" Position
Even though you have "Use Live Positions" checked, your Strategy Code still runs a historical simulation every time the chart updates.
The Simulation: Your strategy logic ran on past bars and found a valid entry signal (e.g., yesterday).
The Ghost: The Backtester opened a theoretical position. LastPosition is now Open in the strategy's memory.
The Plot: PlotStopsAndLimits looks at LastPosition, sees it is Open, and draws the lines.
The Sync (Your Code): Later in your code, you wrote logic to check the Live Account and set foundPosition0 = null. This is the key: You cleared your local variable, but you did not delete the position from WealthLab's internal LastPosition memory. PlotStopsAndLimits ignores your local variable and reads the internal memory instead.
2. Is this bad?
No, it is actually helpful.
It is telling you: "Hey, according to your rules, you SHOULD be in a trade right now."
This visual cue alerts you that there is a Mismatch (Ghost Position) between your strategy logic and your empty Broker account.
3. How to Hide it (The Fix)
If you only want to see stops/limits when you actually have a real position at the Broker, you must wrap the command in an if check that looks at the Live Account (or your synced variable).
Change this line:
To this:
Or, using your specific logic variables:
If you have your foundPosition0 logic set up correctly from the previous steps, you can use that check:
Gemini 3 has suggested some code to check for a live position even though wealth lab also checks to see if the position is at the broker.
I started looking at this when orders are not completely filled within one bar and the position is filled over a couple of bars.
Any ideas on the best approach to get wealthlab to process exactly what is in my broker account?
The reason you see stops and limits is that PlotStopsAndLimits visualizes the Backtester's "Theoretical" Reality, not your Broker's Actual Reality.
Here is the breakdown of why this happens and how to stop it.
1. The Cause: The "Ghost" Position
Even though you have "Use Live Positions" checked, your Strategy Code still runs a historical simulation every time the chart updates.
The Simulation: Your strategy logic ran on past bars and found a valid entry signal (e.g., yesterday).
The Ghost: The Backtester opened a theoretical position. LastPosition is now Open in the strategy's memory.
The Plot: PlotStopsAndLimits looks at LastPosition, sees it is Open, and draws the lines.
The Sync (Your Code): Later in your code, you wrote logic to check the Live Account and set foundPosition0 = null. This is the key: You cleared your local variable, but you did not delete the position from WealthLab's internal LastPosition memory. PlotStopsAndLimits ignores your local variable and reads the internal memory instead.
2. Is this bad?
No, it is actually helpful.
It is telling you: "Hey, according to your rules, you SHOULD be in a trade right now."
This visual cue alerts you that there is a Mismatch (Ghost Position) between your strategy logic and your empty Broker account.
3. How to Hide it (The Fix)
If you only want to see stops/limits when you actually have a real position at the Broker, you must wrap the command in an if check that looks at the Live Account (or your synced variable).
Change this line:
CODE:
PlotStopsAndLimits(6, true, true, WLColor.Blue, WLColor.Pink, WLColor.Green, WLColor.Orange);
To this:
CODE:
// Only plot if we have a Live Position (Broker) OR if we are just Backtesting (No Live Account attached) if (Backtester.LiveAccount == null || Backtester.LiveAccount.Positions.Count > 0) { PlotStopsAndLimits(6, true, true, WLColor.Blue, WLColor.Pink, WLColor.Green, WLColor.Orange); }
Or, using your specific logic variables:
If you have your foundPosition0 logic set up correctly from the previous steps, you can use that check:
CODE:
C# // Only plot if the code confirms the position is Real/Synced if (foundPosition0 != null) { PlotStopsAndLimits(6, true, true, WLColor.Blue, WLColor.Pink, WLColor.Green, WLColor.Orange); }
CODE:Which broker? There can be a small delay - but it should usually be only 1 second max.
between the broker and wealth lab.
Refer to the Accounts Tool (Ctrl + T) to see if WL has the account and position information.
Re: PlotStopsAndLimits()
This is a visual cue for the chart only, but it shows when and where (price) the strategy placed an order. It should be called once (only) in Initialize() if you want to see the dots. It's a mistake to add conditions to it in Execute(). For PlotStopsAndLimits(), either you're going to Plot or "Not". If you want to plot your own dots on a bar-by-bar basis, then you can do that with your own logic with other "Draw" statements.
QUOTE:Are you Auto-Trading? In a single position (per symbol) strategy, if an order is filled partially the rest of the order would be cancelled at the start of the next bar, where the exit logic takes over.
when orders are not completely filled within one bar and the position is filled over a couple of bars.
If you enable Use Live Positions, there's a good amount of studying to do in the Help (F1). In short, this feature is compatible only with strategies that trade one position (per symbol) only - and not external symbols.
Thanks. I'm only doing MNQ. Everything you mentioned seems to be correct. Let me do some more work. I was thinking that given the order manager has a timestamp and the broker has a timestamp and only one position is open at a time that this would be rather straight forward.
The timestamp in the Order Mgr is the local time that the Signal arrived. It does not tell you anything else (like when it filled).
This is basically what I've been working on. So far it does not work as smoothly, but after about 3 1 minute bars pass, then I see the position is sync'd. Also, my original code from Gemini would only run when I entered an orphan position manually. I'll see if this latest response works a bit more smoothly.
If I don't enter orphan positions - manually from the same chart that is running the strategy, then everything seems to be fine.
It would be nice to record the signals during the orphan position. This is a great way to develop trading systems from the standpoint of many traders than don't use back testing or if a position is not filled, or if we want to average down on a position. The extracted signals may come in handy for coding the state machine for that entry.
User
how do deal with orphan positions in wealthlab. Can I add them to my strategy during live trading. Say my strategy buys 4 shares and then later I manually buy 2 shares using the chart that has the strategy running. Can I look at the brokerage live position and sync the 2 toghether?
Model
ThinkingThoughts
Expand to view model thoughts
chevron_right
Yes, you absolutely can sync them. In fact, this is the preferred way to handle "scaling in" manually while letting the algorithm handle the exit for the whole bunch.
Since you are already using the foundPosition0 sync logic in your code, you just need to ensure you are overwriting the Quantity and the Entry Price (Average Cost) with the Broker's data.
Here is how to handle it:
Method 1: The "No Code" Way (Best Practice)
In WealthLab 8, if you check the box "Use Live Positions" in Preferences > Trading:
WealthLab detects your Strategy has a position (Quantity 4).
It polls the Broker and sees the position is actually (Quantity 6).
It automatically updates the Strategy's internal memory to Quantity 6 and updates the Entry Price to the new Average Cost basis.
Your next Sell/Cover signal will generate an order for 6 shares, exiting the whole position.
You usually do not need extra code for this.
Method 2: The Explicit Code Way (For your script)
If you want to be 100% sure your script sees the manual add-on, you update the Quantity and EntryPrice inside your existing sync block.
Crucial Logic:
When you buy 2 extra shares manually at a different price, your Average Entry Price changes. You must sync livePos.BasisPrice to ensuring your Trailing Stops (which are calculated from Entry Price) move to the correct math.
Update your Sync Block (inside Execute) to this:
code
C#
if (foundPosition0 != null)
{
// 1. SYNC PRICE (BasisPrice = The new Average cost of the 6 shares)
foundPosition0.EntryPrice = livePos.BasisPrice;
// 2. SYNC QUANTITY (This captures your manual +2 shares)
// The strategy now thinks it bought all 6.
foundPosition0.Quantity = livePos.Quantity;
// 3. SYNC TYPE (Safety check)
foundPosition0.PositionType = livePos.PositionType;
// 4. SYNC TIMESTAMP (Visuals)
// ... your timestamp logic here ...
// VISUAL CONFIRMATION ON CHART
// This tells you the Strategy successfully "Adopted" the manual shares
string syncMsg = $"Sync: {foundPosition0.Quantity} @ {foundPosition0.EntryPrice:N2}";
DrawText(syncMsg, idx, bars.Low[idx] - (bars.SymbolInfo.TickSize * 20), WLColor.Blue, 10, "Price", true);
}
Important Warnings for Manual Interventions
Direction Mismatch: If your strategy is Long 4, and you manually Short 10 (flipping the position to Net Short -6), the Strategy will get very confused. It will try to "Sell" to exit, which adds to a Short position. Only manually add to the same direction (Long adds to Long).
Stop Management:
Strategy buys 4 @ 100. Stop is 90. Risk is $40.
You buy 2 @ 110. Avg Price becomes 103.33.
Result: The strategy will recalculate the stop based on the new 103.33 price immediately. Be prepared for your Stop Loss order to jump significantly on the next bar.
Partial Exits: If you manually close 2 shares (going from 4 down to 2), the sync logic above works perfectly. The strategy will simply manage the remaining 2.
Summary
Yes, you can do this. Ensure "Use Live Positions" is checked in Preferences, and your existing code (specifically foundPosition0.Quantity = livePos.Quantity) will handle the rest perfectly. The strategy will exit all 6 shares when the signal fires.
If I don't enter orphan positions - manually from the same chart that is running the strategy, then everything seems to be fine.
It would be nice to record the signals during the orphan position. This is a great way to develop trading systems from the standpoint of many traders than don't use back testing or if a position is not filled, or if we want to average down on a position. The extracted signals may come in handy for coding the state machine for that entry.
User
how do deal with orphan positions in wealthlab. Can I add them to my strategy during live trading. Say my strategy buys 4 shares and then later I manually buy 2 shares using the chart that has the strategy running. Can I look at the brokerage live position and sync the 2 toghether?
Model
ThinkingThoughts
Expand to view model thoughts
chevron_right
Yes, you absolutely can sync them. In fact, this is the preferred way to handle "scaling in" manually while letting the algorithm handle the exit for the whole bunch.
Since you are already using the foundPosition0 sync logic in your code, you just need to ensure you are overwriting the Quantity and the Entry Price (Average Cost) with the Broker's data.
Here is how to handle it:
Method 1: The "No Code" Way (Best Practice)
In WealthLab 8, if you check the box "Use Live Positions" in Preferences > Trading:
WealthLab detects your Strategy has a position (Quantity 4).
It polls the Broker and sees the position is actually (Quantity 6).
It automatically updates the Strategy's internal memory to Quantity 6 and updates the Entry Price to the new Average Cost basis.
Your next Sell/Cover signal will generate an order for 6 shares, exiting the whole position.
You usually do not need extra code for this.
Method 2: The Explicit Code Way (For your script)
If you want to be 100% sure your script sees the manual add-on, you update the Quantity and EntryPrice inside your existing sync block.
Crucial Logic:
When you buy 2 extra shares manually at a different price, your Average Entry Price changes. You must sync livePos.BasisPrice to ensuring your Trailing Stops (which are calculated from Entry Price) move to the correct math.
Update your Sync Block (inside Execute) to this:
code
C#
if (foundPosition0 != null)
{
// 1. SYNC PRICE (BasisPrice = The new Average cost of the 6 shares)
foundPosition0.EntryPrice = livePos.BasisPrice;
// 2. SYNC QUANTITY (This captures your manual +2 shares)
// The strategy now thinks it bought all 6.
foundPosition0.Quantity = livePos.Quantity;
// 3. SYNC TYPE (Safety check)
foundPosition0.PositionType = livePos.PositionType;
// 4. SYNC TIMESTAMP (Visuals)
// ... your timestamp logic here ...
// VISUAL CONFIRMATION ON CHART
// This tells you the Strategy successfully "Adopted" the manual shares
string syncMsg = $"Sync: {foundPosition0.Quantity} @ {foundPosition0.EntryPrice:N2}";
DrawText(syncMsg, idx, bars.Low[idx] - (bars.SymbolInfo.TickSize * 20), WLColor.Blue, 10, "Price", true);
}
Important Warnings for Manual Interventions
Direction Mismatch: If your strategy is Long 4, and you manually Short 10 (flipping the position to Net Short -6), the Strategy will get very confused. It will try to "Sell" to exit, which adds to a Short position. Only manually add to the same direction (Long adds to Long).
Stop Management:
Strategy buys 4 @ 100. Stop is 90. Risk is $40.
You buy 2 @ 110. Avg Price becomes 103.33.
Result: The strategy will recalculate the stop based on the new 103.33 price immediately. Be prepared for your Stop Loss order to jump significantly on the next bar.
Partial Exits: If you manually close 2 shares (going from 4 down to 2), the sync logic above works perfectly. The strategy will simply manage the remaining 2.
Summary
Yes, you can do this. Ensure "Use Live Positions" is checked in Preferences, and your existing code (specifically foundPosition0.Quantity = livePos.Quantity) will handle the rest perfectly. The strategy will exit all 6 shares when the signal fires.
Your Response
Post
Edit Post
Login is required