- 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.
//@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) ? sma(src, len) : (v5 * (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 // === /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 ===
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.
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.
it looks to good to work. I'll test it this week if it repaints.
But not at all -> thank you for this script!