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

msammons

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?
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

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.
 
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;
 
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?
 
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);
;
 
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);

p9oye70.png


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.
 
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;
 
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.
 
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.
 
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");
 
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");
 
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

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
518 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top