How to close position at end of day in TOS strategy?

M

msammons

New member
I am running day trading strategies which require that the stock position be closed at end of day. Is there something simple that can be added to the strategy to close the stock position at end of day?
 
M

msammons

New member
That 2 page long script includes extended hours, "-1 offset", "+1 offset", isRollover, chart bubbles, five plots, five color sets, and five labels. That is all a bit complicated. Can anyone cut out the 90% or so unnecessary code there to get to what I need?

I thought it would be as simple as adding into an AddOrder to close based upon a time near the close of trading.
 
S

SimpleStock

New member
This is modified from @korygill's solution but looks give me a plot of last bar I was looking for. I haven't used it for testing systems yet.

declare lower;

def isRollover = GetYYYYMMDD() != GetYYYYMMDD()[1];
def beforeStart = GetTime() < RegularTradingStart(GetYYYYMMDD());

plot lastBarOfDay = if
(isRollover[-1] and beforeStart[-1] == 0)
then 1
else 0;
 
korygill

korygill

Active member
VIP
Why not just close your order when time equals 1259 or when RegularTradingEnd() == GetTime()?
 
M

msammons

New member
Exactly something simple that I was looking for:

but I get a rejection of the RegularTrading End() part of the AddOrder (to close open trade):

def shortexit = x < y;

AddOrder(OrderType.BUY_TO_CLOSE, shortexit or RegularTradingEnd()== GetTime(), Open[-1], 100);

Do you happen to see what code is wrong in the above AddOrder line?
 
korygill

korygill

Active member
VIP
RegularTradingStart(GetYYYYMMDD())
RegularTradingEnd(GetYYYYMMDD())
 
M

msammons

New member
Still says "invalid statement" when I make that change:

AddOrder(OrderType.BUY_TO_CLOSE, shortexit or RegularTradingEnd(GetYYYYMMDD()==GetTime(), Open[-1], 100);
 
korygill

korygill

Active member
VIP
Not at a computer, but looks like your are missing matching parentheses.

AddOrder(OrderType.BUY_TO_CLOSE, shortexit or RegularTradingEnd(GetYYYYMMDD())==GetTime(), Open[-1], 100);

I'd put that in a variable

def eod = RegularTradingEnd(GetYYYYMMDD())==GetTime();

AddOrder(OrderType.BUY_TO_CLOSE, shortexit or eod, Open[-1], 100);
;
 
M

msammons

New member
Thank you Korygill - the code is accepted but it does not trigger eod - perhaps TOS backtesting does not have this capability.
 
korygill

korygill

Active member
VIP
I used the Logic from the Finding the First and Last Bar of the day in ThinkorSwim indicator and created a strategy that buys and sells on the given bar after the start of the day and closes on a given bar at the end of the day.

This was not really hard if you took the logic pieces from that indicator (variables) and got rid of the rest. Hopefully, this is more clear once you view the study below.

Code:
# buy startOffset bars into then open
# close endOffset bars before the close

input startOffset = 5;
input endOffset = 2;

def isRollover = GetYYYYMMDD() != GetYYYYMMDD()[1];
def beforeStart = GetTime() < RegularTradingStart(GetYYYYMMDD());
def afterEnd = GetTime() > RegularTradingEnd(GetYYYYMMDD());
def firstBarOfDay = if
    (beforeStart[1+startOffset] == 1 and beforeStart[startOffset] == 0) or
    (isRollover[startOffset] and beforeStart[startOffset] == 0)
    then 1
    else 0;
def lastBarOfDay = if
    (afterEnd[-1-endOffset] == 1 and afterEnd[endOffset] == 0) or
    (isRollover[-1-endOffset] and firstBarOfDay[-1-endOffset])
    then 1
    else 0;


AddOrder(OrderType.BUY_TO_OPEN, firstBarOfDay[-1], Open[-1], 1);

AddOrder(OrderType.SELL_TO_CLOSE, lastBarOfDay[-1], Open[-1], 1);



Since TOS strategies don't "close" till the next bar, you may need to adjust the AddOrder offset by 1 either way to get your desired outcome.
 
T

tomsk

Well-known member
VIP
To help folks (especially for non-coders) have a better handle on the lastBarOfDay code that @korygill graciously posted above, load the following study on a 5 min chart. The moment the value on the lower chart transitions from 0 to 1, that is the place where the lastBarOfDay is triggered, modulo the specified offset of course. You can then have the confidence that the correct point has been identified.

Code:
declare lower;

input startOffset = 5;
input endOffset = 2;

def isRollover = GetYYYYMMDD() != GetYYYYMMDD()[1];
def beforeStart = GetTime() < RegularTradingStart(GetYYYYMMDD());
def afterEnd = GetTime() > RegularTradingEnd(GetYYYYMMDD());
def firstBarOfDay = if
    (beforeStart[1+startOffset] == 1 and beforeStart[startOffset] == 0) or
    (isRollover[startOffset] and beforeStart[startOffset] == 0)
    then 1
    else 0;
def lastBarOfDay = if
    (afterEnd[-1-endOffset] == 1 and afterEnd[endOffset] == 0) or
    (isRollover[-1-endOffset] and firstBarOfDay[-1-endOffset])
    then 1
    else 0;

plot x = lastBarOfDay;
 
korygill

korygill

Active member
VIP
Thanks @tomsk, I could do a whole post on all the ways I output plots and labels to write and debug variables like this where you don't really know what TOS will do till you experiment. It took me a while to get the knack of TOS scripting, and techniques like you show, really help.
 
M

msammons

New member
Thank you korygill and tomsk - working perfectly now.

If day trading strategies are not closed end of day, the overnight spikes mess up all the results (since, for example, 20 tick stop loss turns into a 200 tick loss overnight) - so being able to close the position near end of day really cleans up the results viewed over 30 days for example.

Again, thank you both for all your help.
 
J

jimothy

New member
Hi all,

Long time lurker, first time poster. Love the community you all have here and how helpful everyone is. I'm hopeful that I can get some of that direct help my way now!

I'm working on a strategy that gets me into a position for day trading. However, since its day trading, I want to make sure I set a AddOrder whenever we are near the end of the day (lets say 5 minutes left in the day, sell!). So I found some helpful code on here, but I'm not seeing it trigger.

Now, I'm thinking that it might not be working because i'm backtesting. i want to essentially try to prove my strategy out, but is the following logic only going to work on the current date, and not work on a lets say 20D chart view? If so, any ideas on how I can reliably say "HEY! THERE ARE 5 MINUTES TO GO, CLOSE A POSITION IF IT EXISTS" and then have AddOrder trigger? That way I can look back at my test and say that all the trades were accurately gotten in and out of on each given day.

The code in question

Code:
input startOffset = 5;
input endOffset = 2;

def isRollover = GetYYYYMMDD() != GetYYYYMMDD()[1];
def beforeStart = GetTime() < RegularTradingStart(GetYYYYMMDD());
def afterEnd = GetTime() > RegularTradingEnd(GetYYYYMMDD());
def firstBarOfDay = if
    (beforeStart[1 + startOffset] == 1 and beforeStart[startOffset] == 0) or
    (isRollover[startOffset] and beforeStart[startOffset] == 0)
    then 1
    else 0;
def lastBarOfDay = if
    (afterEnd[-1 - endOffset] == 1 and afterEnd[endOffset] == 0) or
    (isRollover[-1 - endOffset] and firstBarOfDay[-1 - endOffset])
    then 1
    else 0;

AddOrder(OrderType.SELL_TO_CLOSE, if lastBarOfDay == 1 then lastBarOfDay else Double.NaN, open, name = "SELL.EndOfDay");
 
R

RConner7

Member
Try this - I use these in my strategies and they seem to work.
Code:
##ADD AT TOP OF CODE##
def CloseAllCondition = SecondstillTime(1558) == 0;
def EOD = if SecondsTillTime(1558) == 0 and

             SecondsFromTime(1558) == 0

          then 1

          else 0;


## ADD TOWARDS BOTTOM WITH OTHER AddOrder calls##
AddOrder(OrderType.Sell_TO_CLOSE, EOD or closeAllCondition, price = close, tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "SELL EOD");

AddOrder(OrderType.BUY_TO_CLOSE, EOD or closeAllCondition, price = close, tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "BUY EOD");
 
M

marvhein

New member
I know this thread is a bit old, but someone may come looking for it the way I did.

The above simple examples were very close to workable, but the time assigned to the last bar of the trading day is actually a little before the actual end of the trading day. This amount probably varies by the width of your periods. Just look for them to be pretty close.

For example, the example below worked for me. Tweak the "5" up if you need something slightly higher to slide detection of end of the day into the next to last bar in order to actually close the trade in the last bar of the day. You can plot diff if you need to examine its value at each bar of your chart. (I divided the times by 1000000 to give me something easy to read on the plot.)

def diff = (RegularTradingEnd(GetYYYYMMDD())-GetTime())/1000000;
def eod = diff<5;
 
Last edited:

Similar threads

Top