JayRogers

Open Close Cross Strategy

Revision: 1

Description:
  • Strategy based around Open-Close Crossovers, which can be tuned for smooth trend trading, or with a little care even work for choppy waters.
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 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
//@version=2

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

// === BASE FUNCTIONS ===
// 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 ===
This is a brilliant script that is excellent at backtesting.
However, caught in the wrong situation, codes like this will place multiple orders like mad, and then disappear once the window refreshes.
I found this page looking for a solution to my own script. has anyone had any luck with this issue?
Reply
Has anyone set up an alert system for this?
Reply
It has a repainting issue ever basisLen candles
because security(tickerid, res, exp) and probably with the DEMA too.

CAREFUL WITH LIVE TRANSACTIONS GUYS
Reply
Hi Jay, an excellent strategy. Thank you very much for sharing. I do have a quick query. I've tried modifying the script not to open short trades and only do longs. I've done this by commenting out the 3 strategy entries relating the the short positions. Unfortunately when I do this I no longer get the sell signal for the long position when the shortCond is met?

Any ideas why this would be the case?

Thanks.
Reply
Jay, can you automate trading with this script ?
Reply
chabos PRO Mrgold07
@Mrgold07, There is a Chrome extension called Autoview meant to automate TV strategies. It works by using TV alerts with a custom syntax in the alert description, so you would need to add an alert condition to the script. Also, Autoview for the most part only supports crypto currency exchanges, although they include 1broker, which I have not personally used but apparently allows you to use BTC to trade certain stocks and FX pairs.
Reply
Hello Jay

So you write:
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.

OK, I tell you my experience.
I'm trying using this on SP500 (FX:SPX500 ticker) and Eur50 (EU50EUR ticker of OANDA)
Settings SP500: my TF = 60min / Alternate resolution 240min (I typed 240 in the Default-Value") and used with TEMA/9 periods with trailing stops.
Wonderful backtesting. Really.
Settings on EUR50: my TF 60min / Alternate resolution 1 DAY used with TEMA/10 periods also with trailing stops.
AGAIN sounding wonderful backtesting.

Tested live yesterday and today, and I have PLENTY of FALSE and ghost-signals !
Green streaks turn into red streaks... a complete mess.
On SP500 .. the green streak fades, it turns int a red one... so the strategy gives a "SELL signal" on second hour candle close. OK, than suddenly a "BUY signal" on 3rd hour-candle close.. then I wait for the next hour candle-close, I refresh and BOTH signals are gone... no trace of them.
And the green-streak is still intact .... and it WASN'T at the time it gave the sell signal! Repainted.

Again on Eur50, another example: 12:00 CET BUY signal (more than one hour ago at the time I'm writing) ... I wait 20 minutes, then I refresh the whole chart... and suddenly the BUY SIGNAL is no longer on the 12:00 candle, it lies back on the 9:00 candle, 3 hours before! and the trade is now closed on the candle 12:00..... it make no sense!
The green streak starts now from the candle 8:00... it is solid green now, it WAS red as I was waiting for the new signal..

What the hell, I think: every time I refresh a LIVE chart I get a different picture!
It is a TOTAL DISASTER!

You write: the alternate resolution "should not be lower than chart".
Well this is WRONG... I mean it brings this to work ONLY on backtesting, as the strategy reads past and unmodifiable data!

On LIVE , real-time, is totally different.
And this is the logical reason: whatever "alternate resolution" you choose, the condition is met only when the alternate resolution reaches its CLOSE.
Therefore on OLD data everything looks fantastic... all CLOSE already happened and the strategy must only calculate.

On live ticker the "close" may vary! It could be here on there, and this changes the whole picture every time!
If the close is higher, you get a GREEN streak... if the close is lower you get a red streak... or a swing. And the signals follow.

BUT if I have a timeframe of 1 HOUR, and an alternate resolution of 4 HOURS , I will get a VALID signal only every 4th hour!

Every signal in the meanwhile is wrong or ghosting because subject to change, accordingly to "where the close will be in 2, 3, or 4 hours".
When the alternative CLOSE is reached and the NEW condition is calculated and fixed, then you see a valid signal, which has happened in the past (1 , 2 or 3 hours ago) !

In other words, when I get a signal NOW I do not really know if it is a valid or not, as I have to wait that "alternate resolution" comes to the CLOSE to get whatever kind or confirmation (in my case, at the end of the 4th hour on SP500 and at the end of the day on the EUR50). BUT once the confirmation occurs, everything has already happened!
It is like the strategy tells you now: "Hey man you had to do that 4 hours ago!"
ROFL... THANK YOU !
AFTER that something has happened (ex post) everyone is a genius!
And this make the strategy completely useless for the real-time ... and it is costing me real money... right now.
Reply
Bwinks PRO x_Maurizio
@x_Maurizio, you apparently read NOTHING of this threat and the explanations above.
#Troll
Reply
@Bwinks, Thanks for the reply. I found the strategy and used it after some tweaking. I haven't read much explanations! Why then? This is not quantistic physics. It's only a script.
Whatever. You're PRO.. you know better 4 sure.

I found above these lines . Author writes:
**
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.
**
Well this is exactly what I realized, "it leads to less than optimal signaling". I hadn't noticed it while I did the backtesting.

The use of "long" active periods, 2hrs/4hrs/1day make this almost useless, since the "very last" signal " mentioned above simply arrives too late.
Of course I speak here of intraday trading. Probably position traders could have a different opinion.
I use 1H timeframe, I was looking for a help to find better entry points to execute short trades with a (short) life of 1 to 3 hrs and with high leverage.
I had to use such longer active periods and the final result is that this strategy is useless for my trading.
OK, I correct my statement then.
Probably is not a total disaster, but it needs a lot of "workaround" and compromises.
Reply
oh92 PRO x_Maurizio
@x_Maurizio, I feel your pain. Have you found a fix for this? I created a similar script and im running into the same issues.
Reply
United States
United Kingdom
India
Deutschland
España
France
Việt Nam
Italia
Polska
Brasil
Россия
Türkiye
Indonesia
Malaysia
日本
한국
简体
繁體
Home Stock Screener Forex Signal Finder Cryptocurrency Signal Finder Economic Calendar How It Works Chart Features House Rules Moderators Website & Broker Solutions Widgets Stock Charting Library Feature Request Blog & News FAQ Help & Wiki Twitter
Profile Profile Settings Account and Billing Support Priority Support Report Issue Ideas Published Followers Following Private Messages Chat Sign Out