Open Close Cross Strategy

Revision: 1

  • Strategy based around Open-Close Crossovers, which can be tuned for smooth trend trading, or with a little care even work for choppy waters.
  • I have generally found that setting the strategy resolution to 3-4x that of the chart you are viewing tends to yield the best results, regardless of which MA option you may choose (if any)
  • Don't aim for perfection. Just aim to get a reasonably snug fit with the O-C band, with good runs of green and red.
  • Option to either use basic open and close series data, or pick your poison with a wide array of MA types.
  • Optional trailing stop for damage mitigation if desired (can be toggled on/off)
  • Positions get taken directly following a crossover - which is why it's better to set the resolution of the script greater than that of your chart, so that the trades get taken sooner rather than later.
  • If you make use of the trailing stops, be sure to take your time tweaking the values. Cutting it too fine may cost you profits but keep you safer, while letting them loose could lead to more drawdown than you can handle.
Remove from Favorite Scripts Add to Favorite Scripts

strategy(title = "Open Close Cross Strategy", shorttitle = "OCC Strategy", overlay = true, pyramiding = 0, default_qty_type = strategy.percent_of_equity, default_qty_value = 10)

// Revision:        1
// Author:          @JayRogers
// Description:
//  - Strategy based around Open-Close Crossovers.
// Setup:
//  - I have generally found that setting the strategy resolution to 3-4x that of the chart you are viewing
//    tends to yield the best results, regardless of which MA option you may choose (if any)
//  - Don't aim for perfection. Just aim to get a reasonably snug fit with the O-C band, with good runs of
//    green and red.
//  - Option to either use basic open and close series data, or pick your poison with a wide array of MA types.
//  - Optional trailing stop for damage mitigation if desired (can be toggled on/off)
//  - Positions get taken automagically following a crossover - which is why it's better to set the resolution
//    of the script greater than that of your chart, so that the trades get taken sooner rather than later.
//  - If you make use of the trailing stops, be sure to take your time tweaking the values. Cutting it too fine
//    will cost you profits but keep you safer, while letting them loose could lead to more drawdown than you
//    can handle.

// === INPUTS ===
useRes      = input(defval = true, title = "Use Alternate Resolution? ( recommended )")
stratRes    = input(defval = "120", title = "Set Resolution ( should not be lower than chart )", type = resolution)
useMA       = input(defval = true, title = "Use MA? ( otherwise use simple Open/Close data )")
basisType   = input(defval = "DEMA", title = "MA Type: SMA, EMA, DEMA, TEMA, WMA, VWMA, SMMA, HullMA, LSMA, ALMA ( case sensitive )", type = string)
basisLen    = input(defval = 14, title = "MA Period", minval = 1)
offsetSigma = input(defval = 6, title = "Offset for LSMA / Sigma for ALMA", minval = 0)
offsetALMA  = input(defval = 0.85, title = "Offset for ALMA", minval = 0, step = 0.01)
useStop     = input(defval = true, title = "Use Trailing Stop?")
slPoints    = input(defval = 200, title = "Stop Loss Trail Points", minval = 1)
slOffset    = input(defval = 400, title = "Stop Loss Trail Offset", minval = 1)
// === /INPUTS ===

// Returns MA input selection variant, default to SMA if blank or typo.
variant(type, src, len, offSig, offALMA) =>
    v1 = sma(src, len)                                                  // Simple
    v2 = ema(src, len)                                                  // Exponential
    v3 = 2 * v2 - ema(v2, len)                                          // Double Exponential
    v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)               // Triple Exponential
    v5 = wma(src, len)                                                  // Weighted
    v6 = vwma(src, len)                                                 // Volume Weighted
    v7 = na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len    // Smoothed
    v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))   // Hull
    v9 = linreg(src, len, offSig)                                       // Least Squares
    v10 = alma(src, len, offALMA, offSig)                               // Arnaud Legoux
    type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="HullMA"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1
// security wrapper for repeat calls
reso(exp, use, res) => use ? security(tickerid, res, exp) : exp
// === /BASE FUNCTIONS ===

// === SERIES SETUP ===
// open/close
closeSeries = useMA ? reso(variant(basisType, close, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(close, useRes, stratRes)
openSeries  = useMA ? reso(variant(basisType, open, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(open, useRes, stratRes)
trendState  = closeSeries > openSeries ? true : closeSeries < openSeries ? false : trendState[1]
// === /SERIES ===

// === PLOTTING ===
barcolor(color = closeSeries > openSeries ? #006600 : #990000, title = "Bar Colours")
// channel outline
closePlot   = plot(closeSeries, title = "Close Line", color = #009900, linewidth = 2, style = line, transp = 90)
openPlot    = plot(openSeries, title = "Open Line", color = #CC0000, linewidth = 2, style = line, transp = 90)
// channel fill
closePlotU  = plot(trendState ? closeSeries : na, transp = 100, editable = false)
openPlotU   = plot(trendState ? openSeries : na, transp = 100, editable = false)
closePlotD  = plot(trendState ? na : closeSeries, transp = 100, editable = false)
openPlotD   = plot(trendState ? na : openSeries, transp = 100, editable = false)
fill(openPlotU, closePlotU, title = "Up Trend Fill", color = #009900, transp = 40)
fill(openPlotD, closePlotD, title = "Down Trend Fill", color = #CC0000, transp = 40)
// === /PLOTTING ===

// === STRATEGY ===
// conditions
longCond    = crossover(closeSeries, openSeries)
shortCond   = crossunder(closeSeries, openSeries)
// entries and base exit
strategy.entry("long", strategy.long, when = longCond)
strategy.entry("short", strategy.short, when = shortCond)
// if we're using the trailing stop
if (useStop)
    strategy.exit("XL", from_entry = "long", trail_points = slPoints, trail_offset = slOffset)
    strategy.exit("XS", from_entry = "short", trail_points = slPoints, trail_offset = slOffset)
// not sure needed, but just incase..
strategy.exit("XL", from_entry = "long", when = shortCond)
strategy.exit("XS", from_entry = "short", when = longCond)
// === /STRATEGY ===
Lets see if it works across multiple pairs
Testing on daily basis will be proof of the pudding.
Thanks for working it...enjoy the food now
+3 Reply
Hi; If you have an input to select the MA types which is basicType, then the variant statement defining each; What is the responsibility or function of the statement "type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="HullMA"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1"? Thanks.
JayRogers telepatico
The responsibility of that last line of the variant() function is to return to correct MA type as requested by the user via input.
Also, notice on the input, "DEMA" is repeated twice on that line, so you ended up with 10 defined, but 11 options.
JayRogers telepatico
It appears twice on line 27, but it is not being repeated. The first instance is setting a default for the entry field, otherwise it would remain blank until an entry is given.
telepatico JayRogers
Jay; This is a very nice study and I like it. Just was wondering about the logic used to learn the code purpose line by line. Got it now. Thanks a lot.
JayRogers telepatico
The very heart of it is quite simply to see if the close is higher/lower than the open. In itself that very simple code, the majority of the code in the script is adding additional functionality to help find more optimal conditions in different places.
This script should definitely be very much considered a Work In Progress at this point. There are some kinks that definitely need to be worked out with using alternate resolutions, so if you do decide to use it - please stick to native chart resolution.
Hi, I am new to this, may I know which programming language is this?

Known as "Pine Script", reference and documentation can be found here: https://www.tradingview.com/study-script-reference/
Thanks, first testing looks great! But since can't test it live on a Saturday, does it repaint?
JayRogers cristian.d
I'm actually waiting for monday to get some more testing done... Found some odd repainting happening particularly when using an alternate resolution. Keep it to the same timeframe as your chart for now.
cristian.d JayRogers
Ok, thanks. Sunday afternoon (Pacific time) futures and forex opens so I will be able to test it live. Thanks again for your work.
+1 Reply
JayRogers cristian.d
Please don't hesitate to post any feedback/criticism, kinda feel a bit daft for pulling the trigger too soon on publishing this.. so want to get a fixed up revision out asap lol
cristian.d JayRogers
Don't worry about it.. all the strategies that repaint use open so I guess using close it won't ..how can I set it for the open? No matter what, until the markets open we won't be able to test it properly. But it's really cool, I mean 17 or 18 Profit Factor is unreal, but if it doesn not repaint and get a 4-5 Profit Factor would be amazing
JayRogers cristian.d
In order for a script to not repaint, it has to use "set in stone" data. So that is either data pulled from previous candles and applied to the current candle, or the open of the current candle.

High, Low and Close are all moving targets until the end of a candles time frame.

Unfortunately due to the underlying concept being that the close series must cross the open series in order to find the entry point, there is no just "setting it all to open" to fix it heh.. But adding an additional 1 candle delay on trade entry could maybe have a positive outcome. Perhaps giving and option to allow a custom delay input, so you could adjust from 1-3 candles before order is placed? Seems like something I should at least toy around with.
cristian.d JayRogers
That makes sense
what's the best time frame for this ?
JayRogers bobbyxue
"Best time frame" will always vary, no matter what kind of indication you use from pair to pair. It's always going to be a case of trial and error to fine tune a script - that's why I try to include as many relevant user inputs as possible.
Can it also be used in stocks? and what will be the ideal entry?thanks lol
JayRogers bobbyxue
I honestly can't say, as I focus forex personally. A little trial and error should quickly show you if it's viable.
Is the long or sell signal going to generate on the second candle when there is the third candle comes out? or in other words, is it lagging?
I have tested ur strategy on the stock and it works pretty well. can't wait to test it on monday!
JayRogers bobbyxue
Ultimately yes - the signal will be generated on the second candle, or later. Strategy entries will only ever (currently) execute on the candle AFTER the condition for execution has been met. This is why some strategies execute better when set to the a higher resolution than the chart. For instance, a 15 minute chart where the strategy is run at a 1 hour resolution, the hour in which the condition is met for execution - the execute will run in the first 15 minute portion that it deems viable, rather than waiting for the second hour. In some circumstances this is a good thing, in others it can be a bust.
bobbyxue PRO JayRogers
I have been looking and manually testing your strategy whole day, and this strategy is going to do something for sure. I find it better that I put it in daily chart and set the resolution into 1 w for the stocks
+1 Reply
JayRogers bobbyxue
Over longer time frames it should still be viable to make decisions, at least on the close of a period. Thanks for this feedback; every little helps. :)
+1 Reply
rrajkumar86 JayRogers
@JayRogers, I would like to use this with 1D time frame. In any case can i set 4 days resolution. Personally i feel 1W resolution on 1 day chart giveng delay. Is script needs to be changed?
Nice indicator! Quick question Jay; Do you know why the indicator does't work on SPX500 but works on NAS100? I use the 15 minute timeframe/ set resolution to 1h. thanks
To follow up on my last comment...you should read: Why the the buy and sell arrows won't show up on SPX500 while working on the NAS100. cheers
JayRogers skiislife
I can't comment at this time unfortunately due to the fact I'm trying to work out multiple issues with the script to release a more reliable version. I mostly focus on forex myself - but I will certainly make sure to test on SPX500 though as I get closer to a publication point, to see if there is anything further that may need to be resolved.
any one can create .ex4 file of this script
+1 Reply
Nice system! Seems to be working well with testing done today however the entry points are not exact. By that I mean the system shows a buy signal yet when I refresh the page it disappears and appears on the next candle. I wait 2-3 candles and a few page refreshers before it seems like the buy signal is valid. I think a few tweaks and you will really have something here.

Thanks for the share.
+1 Reply
Thanks for the feedback! I've been working on trying to iron out the dodgy signals, but so far coming up against a brick wall. It's something that occurs frequently when referencing events from higher timeframes with pinescript unfortunately. Having basically exhausted (to my knowledge) all options at this point, I'm now looking to revise it to work from the opposite direction - referencing events on current chart, and acting upon them on the lower. I certainly wont be shelving the concept any time soon.
Entity PRO JayRogers
Just checked on the chart this morning and saw a very interesting picture. I am not all to familiar with the advanced Pine Script functions however I had read some functions result in "repainting" so I am not sure if this is doing the same. The reason repainting is an issue is it is difficult to backtest correctly which results in a higher profit and lower draw down then it would with forward testing. It still seems like the trades if forward tested should still result in some success :)

I have attached a screenshot showing arrows of where the trade first occurred after a few page refreshers and what it looks like now.
+1 Reply
Open Close Cross Strategy V2

At this point I have run out of ideas, and steam, regarding painting issues and the false positives that are the result. I have published my last effort as an idea.

If you wish to grab the updated script, hit the share button and select "make it mine". Cheers.
this is a critique not a criticism but right away, without looking at the code, without even doing an iota of testing, when you see a profit factor of 20 you know right away this is using future data which means it will not work in real world testing. Impressive code though however, keep it up! Just pointing this out to help.
+2 Reply
SPYderCrusher PRO SPYderCrusher
I see judging from the comments you've reached the same conclusion, but in the future you can spare yourself the headache by simply looking at the profit factor. *in general* if its above 3 consistently on multiple out of sample tests its using future data so the threshold there is fairly low.
+1 Reply
JayRogers SPYderCrusher
I appreciate and enjoy feedback and critique in all forms, so long as I can make use of it. Right here, as you've figured, I'm in complete agreement. Although this script has been pretty much rendered into the "concept" category, I'm going to be carrying all that's been learned into future strategy developments. The act of publishing the script in itself was a mistake on my part - I meant to publish as a private idea but was over-tired at the time ..but I rolled with it. The response it has garnered encouraged me to push a lot more effort into it responding to feedback, and thus learned and discovered far more than I otherwise would have. Decent profit factors are definitely attainable, but as you said, anything 4+ should be taken with a grain of salt and a lot a caution.
+1 Reply
good stuff, and cheers! In the real world, profit factor is a moving target. Plenty of strategies are akin to picking up nickels in front of a steam roller -- high odds, low PF. Still, they work. Others, are more swing for the fence style, dependent on 2, 3x PF but the accuracy rate is the big variable. In either case, I am not a quant, but what Ive seen in the real world is that most PF are capped at ~3.

Also, if you really want to go down the rabbit hole, PF is not the best measure necessarily to measure, because there are so many other details worth considering (cost of funds, active risk (which is the std dev of returns) and active return, style return etc etc etc.

anyway, look forawrd to seeing what you come up with next
+1 Reply
You're right that PF above 3 is not possible. But still, when I see a trading system with high PF it creates some excitement and I feel I like have got a jackpot strategy.
+1 Reply
A high PF is often an indication that something is at least being done "right". And in this case I think it's just keeping things simple... I see far too much over-complication in a lot of strategies; keeping concepts simple is where it's at in my view.
Yes true. Your strategy is good. You could make some quick fixes and make it ready to use without any repainting.Performance will definitely go down and that's understandable. You could just release a NonRepaint version of the same strategy - Open Close (NonRepaint). Till you keep improving your original version we will be able to use the nonrepaint one.
+1 Reply
I will definitely revisit it at some point, but for the time being it's burned me out and I need a fresh subject to work with.
Okay I understand that. When you get time try to rework on it so that users like me can start using it in real trading.
yingzhong.xu PRO SPYderCrusher
Yes this strategy actually looks at future data, when you get the close price of a high resolution.
Amazing strategy. I'm trying to implement my own work into to make it better. Just wondering if it repaints, because must prediction systems always have faulty trades.
Hello! I'm new to all this. Would like to know how to implement this code in MetaTrader?

I would not recommend trying to. It is unreliable for real-time trading as it can re-paint (signals can often be false) Only use it as affirmation for continuation of existing trades. If you do wish to use scripts from here in Metatrader, you will need to pass it along to someone who can code for metatrader itself as it is very different from Tradingview's "pinescript". Any logic should carry over just fine though if properly ported.
Hi, thanks for sharing the code, I have learnt a lot of pine techniques from your examples. On the line 47 above "v7 = na(v5) ? sma(src, len) : (v5 * (len - 1) + src) / len // Smoothed", I have compared it with the SSMA indicator and believe it should be "v7 = na(v7) ? sma(src, len) : (v7 * (len - 1) + src) / len". Guess you would like to know. Good day.
+1 Reply
JayRogers samtsui
I think you are correct. I threw the function together quite a while back and have made a few changes over time - evidently something got botched along the way. There have been some instances where MA's have failed to plot correctly live also... The function needs some love, so I'll make sure to try and work out the kinks when I next dive into pine.
Looks very interesting.
Hello Jay,

Not sure if I understand the "repainting" thing that you guys have been talking about. During live trading, do the entry and exit signals change over time?

Do you use this strategy for live trading?

Basically any source that is still in a "floating" state is subject to change and can therefor generate false positives. For example, while looking at the close value of an active 5 minute period, the only truly valid signal will be the very last one given when the period has drawn to an actual close, and a new period opens.

Non repainting indications/signals are drawn from past data which is "set-in-stone" so to speak, and thus cannot change - while far more reliable, it can also lead to less than optimal entry signaling due to the inherent delay...

It's a a trade off between late but relatively safe signals, and early, but far more risky ones.
cjszbd JayRogers
How could I go about changing the code to draw from past data? That way it would not repaint.
change instances of open and close to, open and close. This will make it look at the previous period rather than the current.
JayRogers JayRogers
lost formatting there... open and close
JayRogers JayRogers
ok no brackets allowed.. :/ where instances of open and close occur in the code add a '1' enclosed in square brackets directly after the word, with no spacing
cjszbd JayRogers
Great. Thanks for the help Jay.
Hello Jay,

Is there a reason that i cannot set the resolution higher than 1400? I am trying to use a daily chart and use a resolution higher than 1500.
+1 Reply
Hey Jay,

Was wondering if you could give a hand with making alerts for the XL XS LONG SHORT signals it plots?

I've had a go myself but i'm really not good with scripting :X
Managed to figure half of it out, Switched it to an indicator and got alerts based off the shortCond and longCond.
Any idea's on how I could make some conditions for the XL and XS too?
Prauth tekkzi
@tekkzi, would love to know how you did this. I'm trying to make an alert but no luck
Guys, anyone can tell if this repaints after a long/short arrow appears?

Jay, any way you can add an alert to this strategy? )
+1 Reply
nvcworld Troy7s
Can you please convert this strategy into study
This strategy want show when I copy and paste it.
It does not show when pasted for some reason.Can you please advice?
Hi Im new here, please bear with me if my question is too basic. I have run this and on the charts, I see numbers above or below "long/short", what do those numbers mean?

does anyone know how to make an alert for these signals?
does it repaint?
it simply looks too good to be true...does it repaint?
peba1967 hermion.nuru
it looks to good to work. I'll test it this week if it repaints.
But not at all -> thank you for this script!
Ideas Scripts Chart
United States
United Kingdom
Home Stock Screener Forex Signal Finder Economic Calendar How It Works Chart Features House Rules Moderators For the WEB Widgets Stock Charting Library Priority Support Feature Request Blog & News FAQ Help & Wiki Twitter
Private Messages Chat Ideas Published Followers Following Priority Support Public Profile Profile Settings Account and Billing Sign Out