Include time limit in backtesting strategy?

blindsquirrel

New member
The documentation on time and date functions in thinkscript is pretty thin.

What I need is to limit my strategies trades to Mon-Fri, 8:30 - 3:00 pm (future's market day session).
  • No trades should open before 8:30.
  • All positions should flatten at 5 min before 3:00.

Looking at example scripts that use time, I attempted implementing some code:

Python:
# Flatten is true if we're 5 min or less from end of futures trading
def startTime = 0830;;
def lastFiveMinuteBar = 1455;
def endOfTradingTime = 1500;

def flatten = (GetTime() >= lastFiveMinuteBar AND GetTime() < endOfTradingTime);

But, it doesn't seem to be working.

Is there a way to get human readable time formatting from the GetTime() function?

Any help is appreciated.
 
Yes, it works as intended.

One more question, how to get the average first 30 minutes vol for the last 30 days?
I've been trying to modify the following code but to no avail. It seems I can't define the period.
Code:
def volLast30DayAvg = (volume(period = "DAY")[1] + volume(period = "DAY")[2] +....volume(period = "DAY")[30]) / 30;

Can you help me out? Thank you.

A couple of things. First, you don't need to sum and divide those yourself. There's an Average() function. You should really browse through the list of features available to you in ThinkScript. Sometimes knowing what it can do will give you cool ideas. And sometimes it just saves some typing like with Average().

The next part, comparing volume up to a certain time of day to an average of volume up to a that time of day across multiple days, is a bit more tricky. That concept is known as relative volume (rvol). TOS doesn't have it built in like some platforms so it requires more work on our part. Also, some people refer to % of the average day's total volume as rvol so be careful which examples you use.

There's a thread here which has code you can learn from. https://usethinkscript.com/threads/rvol-relative-volume-indicator-watchlist-for-thinkorswim.1014/ What I use for rvol is based on the code in this comment: https://usethinkscript.com/threads/...chlist-for-thinkorswim.1014/page-7#post-48098 but I made some changes to it.

Being new to ThinkScript I expect you'll have questions while trying to get that to work. If the questions are about the rvol code, it's probably best to ask those in that thread.
 
I have several scans that look at daily and weekly indicators. I have them set to alert when the watchlist changes. I have found that several of these scans will alert each day at 3am. I want to restrict my scans to only start triggering from 7AM to 8PM. I have found several posts that point towards the following code working for this purpose.

Code:
input alertPeriodStart = 700;
input alertPeriodEnd = 2010;

# Ensure the scan only alerts during core hours
def startCounter = SecondsFromTime(alertPeriodStart);
def endCounter = SecondsTillTime(alertPeriodEnd);
def alertPeriod = if startCounter >= 0 and endCounter >= 0 then 1 else 0;
plot scan = alertPeriod;

However when I try this out I don't get the result I would expect. I added this to an existing scan set to 1minute and include EXT hours and ran the scan at 6am and it still produced results. I am not sure if this happened because it is a weekend but I think I have tried this during the week with the same results. It seems like the SecondsFromTime function doesn't work how I would expect.

Testing it out by adding a label to a chart when run at 1:13pm EST on a Sunday SecondsFromTime(1400) reports 12,300 when I would expect it to be negative.

Please let me know if I am on the right track and maybe if the reason I am getting strange values is that the code will only work weekdays.

Thanks,
Nathan
 
A couple of things. First, you don't need to sum and divide those yourself. There's an Average() function. You should really browse through the list of features available to you in ThinkScript. Sometimes knowing what it can do will give you cool ideas. And sometimes it just saves some typing like with Average().

The next part, comparing volume up to a certain time of day to an average of volume up to a that time of day across multiple days, is a bit more tricky. That concept is known as relative volume (rvol). TOS doesn't have it built in like some platforms so it requires more work on our part. Also, some people refer to % of the average day's total volume as rvol so be careful which examples you use.

There's a thread here which has code you can learn from. https://usethinkscript.com/threads/rvol-relative-volume-indicator-watchlist-for-thinkorswim.1014/ What I use for rvol is based on the code in this comment: https://usethinkscript.com/threads/...chlist-for-thinkorswim.1014/page-7#post-48098 but I made some changes to it.

Being new to ThinkScript I expect you'll have questions while trying to get that to work. If the questions are about the rvol code, it's probably best to ask those in that thread.
It looks like https://usethinkscript.com/threads/...tor-watchlist-for-thinkorswim.1014/post-31020
is exactly what I need except it didn't work. The number is off by a lot.

Can you take a look at my reply ? https://usethinkscript.com/threads/...tor-watchlist-for-thinkorswim.1014/post-58089
Thx!
 
I have several scans that look at daily and weekly indicators. I have them set to alert when the watchlist changes. I have found that several of these scans will alert each day at 3am. I want to restrict my scans to only start triggering from 7AM to 8PM. I have found several posts that point towards the following code working for this purpose.

Code:
input alertPeriodStart = 700;
input alertPeriodEnd = 2010;

# Ensure the scan only alerts during core hours
def startCounter = SecondsFromTime(alertPeriodStart);
def endCounter = SecondsTillTime(alertPeriodEnd);
def alertPeriod = if startCounter >= 0 and endCounter >= 0 then 1 else 0;
plot scan = alertPeriod;

However when I try this out I don't get the result I would expect. I added this to an existing scan set to 1minute and include EXT hours and ran the scan at 6am and it still produced results. I am not sure if this happened because it is a weekend but I think I have tried this during the week with the same results. It seems like the SecondsFromTime function doesn't work how I would expect.

Testing it out by adding a label to a chart when run at 1:13pm EST on a Sunday SecondsFromTime(1400) reports 12,300 when I would expect it to be negative.

Please let me know if I am on the right track and maybe if the reason I am getting strange values is that the code will only work weekdays.

Thanks,
Nathan

Your code looks fine to me, though very verbose. If I add this as the only criteria in a scan it's working to cause no results. I had it set to All Symbols and returning up to 10 results. Added this in a study filter and then it's 0 results. Remove this and it's back to 10 results.
Ruby:
plot scan = SecondsFromTime(0700) >= 0 and SecondsTillTime(2010) >= 0;

Or if you want the inputs:
Ruby:
input start = 0700;
input end = 2010;
plot scan = SecondsFromTime(start) >= 0 and SecondsTillTime(end) >= 0;
 
Hello,
I have a simple strategy that I want to backtest, however, I want to just get the results during normal trading hour not premarket or aftermarket how do I go about doing that?

I know I can turn off PM/AF in TOS's settings however doing so does throw the MACD values off since it does not have continuous data from premarket. I came across few scanner codes that someone scripted to scan only after the market opens and I tried to Frankenstein that code to my current strategy code and it was a no go, keep getting erros. any help will greatly appreciated

Code:
Def buy = MACD()."Value" crosses above MACD()."Avg";

Def Sell = MACD()."Value" crosses below MACD()."Avg";

input tradeSize = 10;

AddOrder(OrderType.BUY_TO_OPEN, BUY, open[0], tradeSize, Color.CYAN, Color.CYAN);

AddOrder(OrderType.SELL_TO_CLOSE, sell, close[1], tradeSize, Color.MAGENTA, Color.MAGENTA);
 
I want to backtest a strategy that involves repeatedly buying or selling at an exact time every day. Is there a way to do this in ThinkScript? It seems to be kind of unintuitive. I'm still somewhat new to writing scripts so I'm probably just missing something obvious but I can't seem to find any answers in the learning center or through google searching and browsing forums.

Lets say I want to buy shares of a given company at 11:37 AM every trading day and sell at 2:54. Any ideas on how to best format that? I've tried SecondsTill/From but those won't work on larger time frames for backtesting and it didn't seem to trigger that way anyways.

Thanks for any help you can provide!
 
I've been trying to limit my back test strategy to only work during open hours. For me that is 0830 to 1500. Also it doesn't appear to be working like I intended. I have 3 addorder's, 1 for my entry, 1 for my stop, and 1 for my target. Can you help? Thanks!

Code:
input Size = 100;
input OpenTime = 0830;
input CloseTime = 1500;

def positive =MACD()."Value" crosses above MACD()."Avg" and MACD()."avg" is less than or equal to MACD()."ZeroLine" and close is greater than MovAvgExponential("length" = 200)."AvgExp" ;

def negative =MACD()."Value" crosses below MACD()."Avg" and MACD()."avg" is greater than or equal to MACD()."ZeroLine" and close is less than MovAvgExponential("length" = 200)."AvgExp" ;

def atr = reference ATR();


def condition = SecondsFromTime(OpenTime) == 0 and positive;

# Entry
AddOrder(type = OrderType.BUY_AUTO, tickcolor = Color.GREEN, arrowcolor = Color.GREEN, name = "Long", tradeSize = Size, condition = condition);

# Stop
AddOrder(type = OrderType.SELL_TO_CLOSE, SecondsFromTime(CloseTime) == 0 or EntryPrice() - ATR(), tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "stop");
# Target
AddOrder(type = OrderType.SELL_TO_CLOSE, SecondsFromTime(CloseTime) == 0 or EntryPrice() + ATR()*2, tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "Target");
 
@purple You can place Conditional Market Orders at specific times as one of the conditions but conditional orders are a once-and-done order... You can save the conditional order and re-invoke it every day, or night, so it triggers at the specific time... In order for it to fully work as you want you would most likely need to create custom Study code within the conditional order... It would take a lot of typing and images to explain how to go about doing this so I will leave it up to you to research Conditional Orders and watch videos on the subject... Once you have done so, if you have additional targeted questions then we could assist further... I am assuming that you are referring to real trading rather than simply backtesting... I can't say whether this would work for backtesting as the AddOrder() function is paltry in performance at best...
 
@RegularRob Please use the search feature as this same question has been asked and answered in recent days or weeks... It doesn't warrant starting yet another topic... Perhaps @BenTen can merge this topic with one that contains the answer...
 
Awesome, got the time to work! Thanks! Do you see any other errors in my code? My target order never activates, only the stop order.

Code:
input Size = 100;
input usetimefilter = Yes;
input rthopen = 0931;
input rthclose = 1555;

def RTH = if usetimefilter == yes then if SecondsFromTime(rthopen) >= 0 and
               SecondsTillTime(rthclose) >= 0
            then 1
            else 0 else 1;

def positive =MACD()."Value" crosses above MACD()."Avg"  and MACD()."avg" is less than or equal to MACD()."ZeroLine"  and close is greater than MovAvgExponential("length" = 200)."AvgExp"  ;

def negative =MACD()."Value" crosses below MACD()."Avg"  and MACD()."avg" is greater than or equal to MACD()."ZeroLine"  and close is less than MovAvgExponential("length" = 200)."AvgExp" ;

def atr = reference ATR();



# Entry
AddOrder(type = OrderType.BUY_TO_OPEN, tickcolor = Color.GREEN, arrowcolor = Color.GREEN, name = "Long", tradeSize = Size, condition = rth and positive);

# Stop
AddOrder(type = OrderType.SELL_TO_CLOSE, rth and EntryPrice() - (ATR()*2), tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "stop");

# Target
AddOrder(type = OrderType.SELL_TO_CLOSE, rth and EntryPrice() + (ATR()*2)*2, tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "Target");
 
@RegularRob Replace those.
Code:
# Stop
AddOrder(type = OrderType.SELL_TO_CLOSE, rth and close crosses below EntryPrice() - (ATR()*2), tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "stop");

# Target
AddOrder(type = OrderType.SELL_TO_CLOSE, rth and close crosses above EntryPrice() + (ATR()*2)*2, tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "Target");
 
@RegularRob Replace those.
Code:
# Stop
AddOrder(type = OrderType.SELL_TO_CLOSE, rth and close crosses below EntryPrice() - (ATR()*2), tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "stop");

# Target
AddOrder(type = OrderType.SELL_TO_CLOSE, rth and close crosses above EntryPrice() + (ATR()*2)*2, tickcolor = Color.DARK_RED, arrowcolor = Color.DARK_RED, name = "Target");
That did it, thanks!
 

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
236 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