MIH8
- ago
Hi team.

Although I am aware that some functions in WL work only for backtests, I am very surprised that this function does not work properly in (automatic) trading.

Might this be a broker related issue or what is the reason that new orders are placed although there is an existing position at the broker?

Please have a look at it.
0
721
Solved
17 Replies

Reply

Bookmark

Sort
Cone8
 ( 24.80% )
- ago
#1
Strategies ALWAYS operate in a hypothetical backtest mode. With the Portfolio Sync function, its not a problem for exiting positions (orders are ignored if a live Position doesn't exist). However, if you already have a live position and you don't want to add to it, then you need to make your hypothetical strategy aware of it.

Vote:
https://www.wealth-lab.com/Discussion/Access-Accounts-data-from-broker-programmatically-7914
1
MIH8
- ago
#2
Ok, thanks for your feedback. Here is my opinion on that.

If you offer an automated trading mode in your software, it must be prepared to provide the same functionality for both modes, at least in terms of basic functionality. You can certainly find this function in 95% of all strategies.

If one uses again and again functions, which one maps for real trading with a workaround the use is lost.
From my point of view, once again not well thought out.

I have already voted for the feature, but I did not think of such elementary basics to control the automated trading.

0
MIH8
- ago
#3
Can you please explain how the behaviour of this code is while trading

CODE:
if (!HasOpenPosition(bars, PositionType.Long)) { // 1. When is this code executed in trading?! // 2. How must this look like, so that it is functionally identical in the backtest and in trading? // 3. What is the point of writing code (block, self-implemented) that must be different and modified for trading? } else { // do something }


QUOTE:

... With the Portfolio Sync function, its not a problem for exiting positions ...


I don't know what you are referring to, can you please give me another hint.
0
Glitch8
 ( 9.89% )
- ago
#4
The point is to keep the integrity of the state of the trading system. Cone already answered, WL strategies are always based on hypothetical positions.

Once exit signals are issued, they can then be synchronized to actual positions held in a broker account.
0
- ago
#5
QUOTE:
I don't know what you are referring to, can you please give me another hint.

The built-in Help is the best resource to refer as another hint. Type in "portfolio sync" in Filter and please read the "Trading Preferences" chapter where it's been described in detail with embedded Youtube links.
0
MIH8
- ago
#6
QUOTE:
The point is to keep the integrity of the state of the trading system. Cone already answered, WL strategies are always based on hypothetical positions.


I understood that it is based on hypothetical positions of a backtest.
But this does not answer what the code is doing when trading!

Sorry Glitch, now a very basic and simple question. I has nothing to do with synchronization of the positions.

When trading, is this branch of code always, never, systematically or randomly executed?

You can't sugarcoat this point. There can be a lot more calculations that are not directly related to place a trade and to sync with the broker. Everything that is coded within this block is affected. You just have to know how the function behaves, i.e. how the return values are generated, otherwise controlling the branch and its contents is impossible!

@Eugene Thanks for the reference.
0
Glitch8
 ( 9.89% )
- ago
#7
HasOpenPosition checks to see if the simulation has an open position at the point in time it is called. It doesn’t have anything to do with live trading.

In a live trading scenario, we’re only concerned with the last bar of data, the one that generates signals. If there is a theoretical position open in the backtest as of the last bar of data, then that code will execute.

Hope that clears things up 🙂
1
- ago
#8
So on the last bar of execution, will HasOpenPosition check if there is a real position in my brokerage account?
0
- ago
#9
To check if there is a real position in your brokerage account, you can use C# code solution referenced in the topic in @Cone's Post #1.
0
Cone8
 ( 24.80% )
- ago
#10
This topic has aged. There is a new Trading Preference, Live Positions, that changes things a bit. See the User Guide for details.

In short, in a Streaming Strategy Window or in the Strategy Monitor with the Live Positions option enabled, HasOpenPosition essentially checks for a real position in a brokerage account. Otherwise, it does not.
1
Best Answer
- ago
#11
I have a manually purchased position like TQQQ. Would the HasOpenPosition function pick that up if the Live Position is check-marked? If so, I can't seem to get it to sell my existing position.
0
- ago
#13
Strategy Monitor. As far as I can tell, it looks like everything is connected.
I've included everything to give you some context. I was running this code using 15-minute data, but for the sake of forcing it to do something, I used 1-minute data.
The image I copied was just after closing today. Previously, I accidentally deleted the strategy from the monitor and had to re-add it to get the image.

CODE:
/* This code has been modified using the One Percent A Week Strategy. Assign TQQQ to a Market that opens at 09:29 EST (Tools > Markets & Symbols) Use a 15-minute data scale. */ using WealthLab.Backtest; using System; using WealthLab.Core; namespace WealthScript1 {    public class RunAnyDayStrategy : UserStrategyBase    {       public override void Initialize(BarHistory bars)       {          PlotStopsAndLimits(3);       }       public override void Execute(BarHistory bars, int idx)       {          if (idx >= bars.Count - 1)             return;          // FIRST TRADING DAY OF WEEK LOGIC          if (TodayIsFirstSessionOfTheWeek(bars, bars.DateTimes[idx]))          {             // Ensure Filter Pre/Post Market Data is checked!             if (!HasOpenPosition(bars, PositionType.Long))             {                int firstBarToday = idx - bars.IntradayBarNumber(idx);                if (bars.DateTimes[firstBarToday].TimeOfDay == ts0930) // the first bar was the premarket bar ending at 0930                {                   if (idx > firstBarToday)                   {                      _limit = bars.Open[firstBarToday + 1] * 0.99;                   }                   else                   {                      // use the close of the last premarket bar                      _limit = bars.Close[firstBarToday] * 0.99;                   }                }                else // the first bar was not a premarket bar                   _limit = bars.Open[firstBarToday] * 0.99;                PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, _limit);                return;             }             SetBackgroundColor(bars, idx, WLColor.FromArgb(40, WLColor.Red));             return;          }          else          {             SetBackgroundColor(bars, idx, WLColor.FromArgb(40, WLColor.Red));             // Ensure Filter Pre/Post Market Data is checked!             if (HasOpenPosition(bars, PositionType.Long))             {                SetBackgroundColor(bars, idx, WLColor.FromArgb(40, WLColor.Orange));                target = LastOpenPosition.EntryPrice;                pct_profit_or_loss = LastOpenPosition.ProfitPctAsOf(idx);                target = LastOpenPosition.EntryPrice;                if (pct_profit_or_loss > -0.5)                {                   target *= 1.01;                   WLHost.Instance.AddLogItem("Sell", "Trying to sell @ " + target.ToString(), WLColor.Red);                   PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, target);                      }                // Sell TQQQ if the loss < 15 percent (temporarily changed it zero to force a trade)                else if (pct_profit_or_loss < 0.0)                {                   WLHost.Instance.AddLogItem("Sell", "Trying to sell @ " + bars.Close[idx].ToString(), WLColor.Orange);                   PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, bars.Close[idx]);                }             }          }       }       // pass the current date to check with the bars       public bool TodayIsFirstSessionOfTheWeek(BarHistory bars, DateTime dte)       {          if (!bars.Market.IsTradingDay(dte.Date))             return false;          DayOfWeek dow = dte.DayOfWeek;          do          {             dte = dte.AddDays(-1);             if (bars.Market.IsTradingDay(dte.Date))                return dow < dte.DayOfWeek;          }          while (dte.Year > 1900);          return false;       }       TimeSpan ts0930 = new TimeSpan(9, 30, 0);       double _limit = 0;       private double pct_profit_or_loss = 0.0;       private double target = 0.0;    } }



0
Cone8
 ( 24.80% )
- ago
#14
QUOTE:
I have a manually purchased position like TQQQ. Would the HasOpenPosition function pick that up if the Live Position is check-marked?
Yes, but I've found a bug...

The script must have created at least one position previously. You can exit that hypothetical Position(s) - or not - and the script will pick up the Live Position on the last bar.
0
Cone8
 ( 24.80% )
- ago
#15
Remove this statement - that disables Signals!

CODE:
         if (idx >= bars.Count - 1)             return;


If you load at least 2 weeks of data, then it should work (as long as at least one position was created in the past).
0
- ago
#16
Thank you very much for all your help.

I’ll try this change on Monday.

Mike
0
Cone8
 ( 24.80% )
- ago
#17
By the way, just to be sure, you know that the script above was modified from the "One Percent Per Week" intraday strategy to:
1. exit at any loss beginning on the second day of the week, and,
2. only enter a position on the first day of the week.

Both of these will cause the performance of the system to suffer.
0

Reply

Bookmark

Sort