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?
 
I now use this amazingly short and simple code from Member RConner7:

##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");
 
@msammons Isn't all of this code just a roundabout way of entering a Market On Close order as a stop-gap to holding overnight...??? Have I missed some logic to the contrary...??? Granted, a MOC order can't be configured in a script but how hard is it to enter on manually or in an order template...???

True, but I don't backtest such long periods so manual calcs of a few possible trades isn't that bad... Why would I trade the same instrument every day for 100 days and close at the end of every day...??? Just doesn't seem like a sound trading strategy to me is all... If that's what works for you, great...!!!

I only day trade and have never, nor will I ever, trade on margin... I don't have credit cards or loans either... I'm just a cash kinda guy... I carry no debt... Like I said, if it works for you, great...!!! ;) (y)
 
Last edited by a moderator:
I now use this amazingly short and simple code from Member RConner7:

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

Hey! Just wanted to add that I’m trying this code in one of my strategies and if doesnt seem to be triggering for the “show report” or plot the sell order on the chart... so not sure if you have any tips why it wouldn’t fire.

I am backtesting against a 15 minute chart so my understanding is that if the buy to open fires multiples times per day or multiple days, each individual EOD would chose a 0 position target right?

Thanks!

Chad
 
Hey! Just wanted to add that I’m trying this code in one of my strategies and if doesnt seem to be triggering for the “show report” or plot the sell order on the chart... so not sure if you have any tips why it wouldn’t fire.

I am backtesting against a 15 minute chart so my understanding is that if the buy to open fires multiples times per day or multiple days, each individual EOD would chose a 0 position target right?

Thanks!

Chad
I stumbled across this thread again while considering using conditional orders for EOD so I don't have to be awake at almost 5am in my local time to close day trades that haven't stopped out or reached their targets. I noticed this question was never answered and I believe I can provide a better solution.

I used some ideas from this thread when I needed an EOD exit for a strategy some months ago. The example code:
Ruby:
def EOD = if SecondsTillTime(1558) == 0 and SecondsFromTime(1558) == 0 then 1 else 0;
only works on 1 minute charts. The start time of the last bar of the day is different on each timeframe and we need the time to be earlier than the start of that bar.

At the time I played with this I ended up using an if else block to set the correct time for the few timeframes I cared about. However, a better solution is possible. Typically in enumerations programmers use a zero-based index, or sometimes, a hexadecimal index which allows a single value to represent multiple list items selected. However, I recently noticed in the AggregationPeriod enumeration the TOS programmers used the number of milliseconds represented by each timeframe as its index. This means we can do time math based on AggregationPeriod.

Please forgive any typos or errors in my code blocks. I'm just typing this stuff here.

For instance, and this one would work even if it was a zero-based incremented index, you can use less than and greater than with timeframes, not only equals.
Ruby:
def isIntraday = if GetAggregationPeriod() < AggregationPeriod.DAY then 1 else 0;

For the end of day exit, we can do this:
Ruby:
def EOD = RegularTradingEnd(GetYYYYMMDD())  - GetTime() <= GetAggregationPeriod() - 1;

Remember that the value returned by GetAggregationPeriod() is the number of milliseconds duration of the period so we can multiply if we want to end at the second last bar instead of the last.
Ruby:
input barsFromEnd = 2;
def EOD = RegularTradingEnd(GetYYYYMMDD()) - GetTime() <= GetAggregationPeriod() * barsFromEnd - 1;

We still need the look-ahead -1 index.
If you're looking for a solution to copy/paste, this is the code block you want.
Ruby:
input barsFromEnd = 1;
def EOD = RegularTradingEnd(GetYYYYMMDD()) - GetTime() <= GetAggregationPeriod() * barsFromEnd - 1;
AddOrder(OrderType.SELL_TO_CLOSE, EOD[-1], close[-1], 0, Color.ORANGE, Color.ORANGE, "EOD LX");
AddOrder(OrderType.BUY_TO_CLOSE, EOD[-1], close[-1], 0, Color.ORANGE, Color.ORANGE, "EOD SX");
 
I stumbled across this thread again while considering using conditional orders for EOD so I don't have to be awake at almost 5am in my local time to close day trades that haven't stopped out or reached their targets. I noticed this question was never answered and I believe I can provide a better solution.

I used some ideas from this thread when I needed an EOD exit for a strategy some months ago. The example code:
Ruby:
def EOD = if SecondsTillTime(1558) == 0 and SecondsFromTime(1558) == 0 then 1 else 0;
only works on 1 minute charts. The start time of the last bar of the day is different on each timeframe and we need the time to be earlier than the start of that bar.

At the time I played with this I ended up using an if else block to set the correct time for the few timeframes I cared about. However, a better solution is possible. Typically in enumerations programmers use a zero-based index, or sometimes, a hexadecimal index which allows a single value to represent multiple list items selected. However, I recently noticed in the AggregationPeriod enumeration the TOS programmers used the number of milliseconds represented by each timeframe as its index. This means we can do time math based on AggregationPeriod.

Please forgive any typos or errors in my code blocks. I'm just typing this stuff here.

For instance, and this one would work even if it was a zero-based incremented index, you can use less than and greater than with timeframes, not only equals.
Ruby:
def isIntraday = if GetAggregationPeriod() < AggregationPeriod.DAY then 1 else 0;

For the end of day exit, we can do this:
Ruby:
def EOD = RegularTradingEnd(GetYYYYMMDD())  - GetTime() <= GetAggregationPeriod() - 1;

Remember that the value returned by GetAggregationPeriod() is the number of milliseconds duration of the period so we can multiply if we want to end at the second last bar instead of the last.
Ruby:
input barsFromEnd = 2;
def EOD = RegularTradingEnd(GetYYYYMMDD()) - GetTime() <= GetAggregationPeriod() * barsFromEnd - 1;

We still need the look-ahead -1 index.
If you're looking for a solution to copy/paste, this is the code block you want.
Ruby:
input barsFromEnd = 1;
def EOD = RegularTradingEnd(GetYYYYMMDD()) - GetTime() <= GetAggregationPeriod() * barsFromEnd - 1;
AddOrder(OrderType.SELL_TO_CLOSE, EOD[-1], close[-1], 0, Color.ORANGE, Color.ORANGE, "EOD LX");
AddOrder(OrderType.BUY_TO_CLOSE, EOD[-1], close[-1], 0, Color.ORANGE, Color.ORANGE, "EOD SX");
Amazingly simple and effective code Slippage! Works great (I am using 1 minute charts).
 
I stumbled across this thread again while considering using conditional orders for EOD so I don't have to be awake at almost 5am in my local time to close day trades that haven't stopped out or reached their targets. I noticed this question was never answered and I believe I can provide a better solution.

I used some ideas from this thread when I needed an EOD exit for a strategy some months ago. The example code:
Ruby:
def EOD = if SecondsTillTime(1558) == 0 and SecondsFromTime(1558) == 0 then 1 else 0;
only works on 1 minute charts. The start time of the last bar of the day is different on each timeframe and we need the time to be earlier than the start of that bar.

At the time I played with this I ended up using an if else block to set the correct time for the few timeframes I cared about. However, a better solution is possible. Typically in enumerations programmers use a zero-based index, or sometimes, a hexadecimal index which allows a single value to represent multiple list items selected. However, I recently noticed in the AggregationPeriod enumeration the TOS programmers used the number of milliseconds represented by each timeframe as its index. This means we can do time math based on AggregationPeriod.

Please forgive any typos or errors in my code blocks. I'm just typing this stuff here.

For instance, and this one would work even if it was a zero-based incremented index, you can use less than and greater than with timeframes, not only equals.
Ruby:
def isIntraday = if GetAggregationPeriod() < AggregationPeriod.DAY then 1 else 0;

For the end of day exit, we can do this:
Ruby:
def EOD = RegularTradingEnd(GetYYYYMMDD())  - GetTime() <= GetAggregationPeriod() - 1;

Remember that the value returned by GetAggregationPeriod() is the number of milliseconds duration of the period so we can multiply if we want to end at the second last bar instead of the last.
Ruby:
input barsFromEnd = 2;
def EOD = RegularTradingEnd(GetYYYYMMDD()) - GetTime() <= GetAggregationPeriod() * barsFromEnd - 1;

We still need the look-ahead -1 index.
If you're looking for a solution to copy/paste, this is the code block you want.
Ruby:
input barsFromEnd = 1;
def EOD = RegularTradingEnd(GetYYYYMMDD()) - GetTime() <= GetAggregationPeriod() * barsFromEnd - 1;
AddOrder(OrderType.SELL_TO_CLOSE, EOD[-1], close[-1], 0, Color.ORANGE, Color.ORANGE, "EOD LX");
AddOrder(OrderType.BUY_TO_CLOSE, EOD[-1], close[-1], 0, Color.ORANGE, Color.ORANGE, "EOD SX");
So if I want to only limit buy_to_open orders on the 1 min chart to less then 12 pm I just need to calculate the bars from 12 pm to close and enter a barsfromend into the buy_to_open code correct?
 
So if I want to only limit buy_to_open orders on the 1 min chart to less then 12 pm I just need to calculate the bars from 12 pm to close and enter a barsfromend into the buy_to_open code correct?

For that case, I wouldn't approach it that way. Instead, I would add a new time-based condition to whatever triggers a buy order. For instance:

Ruby:
def trigger = [whatever] and SecondsTillTime(1200) > 0;
AddOrder(OrderType.BUY_TO_OPEN, trigger);
 
For that case, I wouldn't approach it that way. Instead, I would add a new time-based condition to whatever triggers a buy order. For instance:

Ruby:
def trigger = [whatever] and SecondsTillTime(1200) > 0;
AddOrder(OrderType.BUY_TO_OPEN, trigger);
I tried adding this to the script, however it does not seem to open a buy order. Is it possible to send the script to you directly?

Here's what I did. This strat uses a standard deviation channel and only enters buy orders when it is below a certain level of the channel. I also use the waverider indicator to trigger the buy once it hits below the certain bar on the standard deviation channel.

This is the regular buy order:


AddOrder(OrderType.BUY_TO_OPEN, wt1 crosses above wt2 and wt1 < over_sold_2 and P1 < -0.9, tickcolor = GetColor(0), arrowcolor = GetColor(0), name = "WaveRider Buy!");

This is the new trigger order I used with your code:

def trigger = wt1 crosses above wt2 and wt1 < over_sold_2 and P1 < -0.9 and SecondsTillTime(1200) > 0;
AddOrder(OrderType.BUY_TO_OPEN, trigger, tickcolor = GetColor(0), arrowcolor = GetColor(0), name = "WaveRider Buy Trigger!");

What do you think?
 
Last edited:
For that case, I wouldn't approach it that way. Instead, I would add a new time-based condition to whatever triggers a buy order. For instance:

Ruby:
def trigger = [whatever] and SecondsTillTime(1200) > 0;
AddOrder(OrderType.BUY_TO_OPEN, trigger);
Well I am an ***** had to change the settings to stop the old orders because my global settings were for only 1 trade.

Thanks!
 
Well I am an ***** had to change the settings to stop the old orders because my global settings were for only 1 trade.

Thanks!

Sorry, I must have missed your previous message. Sometimes I have a lot of new notifications when I open the site so I may occasionally miss something. It sounds like you worked out the problem. All good now?
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
433 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