When using Indicators with Automated BUY_TO_OPEN, How do you set the The indicator to view 1min or 5 min bars?

buzzmuff

New member
First timer here, i'm using a script that measures MACD and when the MACD is at the bottom it creates an up arrow and triggers a buy order.

input fastLength = 12;
input slowLength = 26;
input MACDLength = 9;
input percentLossGoal = -2;

plot UpArrow = If(MinArrow == 0, Value, Double.NaN);
UpArrow.AssignValueColor(Color.GREEN);
UpArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpArrow.SetLineWeight(1);
UpArrow.HideBubble();

AddOrder(OrderType.BUY_TO_OPEN, UpArrow, open[1], tradeSize, Color.CYAN, Color.CYAN);

Now when backtesting this strategy I get different results if I'm viewing a 1D:1minute timeline vs a 5D:5Minute timeline.

I'm curious when these Buy to OPEN orders occur, what timeframe is the trigger happening on? Is it doing 1 hour candle bars or 1 minute?

How do i create 2 different scripts, one that buys when the Up-arrow occurs on a 1min timeline, and a separate script for 5min timeline?

Thanks!
 

Slippage

Well-known member
The timeframe it uses is the timeframe of the chart you're looking at. MACD will have a different value on every timeframe so your triggers will be different on every timeframe. In case you're not aware, AddOrder creates simulated, fake orders. It's just a feature for testing your strategy. It won't do any actual trading. The orders don't exist outside of the chart.

If you want to run it on multiple timeframes simultaneously you can split your screen into multiple charts and set each to the timeframe you want. But that will give you separate profit/loss tracking and reporting.

Or, if you want to run it on multiple timeframes from a single chart and get aggregated P&L results you can copy the code from MACD into your strategy and where the close price is used make it close(period=AggreationPeriod.FIVE_MIN). Then use the result from that to create orders in additional to the orders created by your existing code. This will only work on the specified timeframe and lower timeframes. If you set it for 5m and switch your chart to 10m it'll error. Switch to 1m 2m 3m 4m 5m and it'll work. You can have this all in one script or split it into two.

I noticed in your AddOrder call you have it buying at the price of open[1]. This means it's buying using a past price. For instance, on a daily chart it's saying buy me the stock tomorrow but at yesterday's opening price. You want to use open[-1] so it buys at tomorrow's opening price.

Lastly, MACD has no bottom. It has no fixed range and its range will vary widely from stock to stock and timeframe to timeframe. You could, in theory, look for a series of lower values followed by a higher value and define that as a bottom but I'd advise against it in low timeframes. You'll find that, just like price, MACD will often rise slightly and then continue lower.
 

buzzmuff

New member
The timeframe it uses is the timeframe of the chart you're looking at. MACD will have a different value on every timeframe so your triggers will be different on every timeframe. In case you're not aware, AddOrder creates simulated, fake orders. It's just a feature for testing your strategy. It won't do any actual trading. The orders don't exist outside of the chart.

If you want to run it on multiple timeframes simultaneously you can split your screen into multiple charts and set each to the timeframe you want. But that will give you separate profit/loss tracking and reporting.

Or, if you want to run it on multiple timeframes from a single chart and get aggregated P&L results you can copy the code from MACD into your strategy and where the close price is used make it close(period=AggreationPeriod.FIVE_MIN). Then use the result from that to create orders in additional to the orders created by your existing code. This will only work on the specified timeframe and lower timeframes. If you set it for 5m and switch your chart to 10m it'll error. Switch to 1m 2m 3m 4m 5m and it'll work. You can have this all in one script or split it into two.

I noticed in your AddOrder call you have it buying at the price of open[1]. This means it's buying using a past price. For instance, on a daily chart it's saying buy me the stock tomorrow but at yesterday's opening price. You want to use open[-1] so it buys at tomorrow's opening price.

Lastly, MACD has no bottom. It has no fixed range and its range will vary widely from stock to stock and timeframe to timeframe. You could, in theory, look for a series of lower values followed by a higher value and define that as a bottom but I'd advise against it in low timeframes. You'll find that, just like price, MACD will often rise slightly and then continue lower.
Thank you Slippage, it appears the Strategy I'm using is not a Valid strategy for automated trading... It appears it's setting buy triggers in the past, and also looking ahead when backtesting which it wouldn't be able to do in real time...

Any chance you could modify the script so it buys in real time or next candle and not in the past, as well as any arrows that are created are only able to look at Real time and past, not future as it does with backtesting. I've highlighted a few in bold that I believe may work in backtesting but not in real time automated trading.


#MACD based on Hull Moving Average W/peak/ebb arrows
#TOS title = MACD_via_Hull_MA_fav




#INPUTS*****

input tradeDollars = 1000;

def tradesize = Round (tradeDollars / close);

input fastLength = 12;
input slowLength = 26;
input MACDLength = 9;
input AverageType = {SMA, EMA, default HULL};
input percentGainGoal = 5;
input percentLossGoal = -2;



#DEFINE****

def percentChange = 100 * (close - EntryPrice()) / EntryPrice();


#PLOTS****





plot Value;
plot Avg;
switch (AverageType) {
case SMA:
Value = Average(close, fastLength) - Average(close, slowLength);
Avg = Average(Value, MACDLength);
case EMA:
Value = ExpAverage(close, fastLength) - ExpAverage(close, slowLength);
Avg = ExpAverage(Value, MACDLength);
case HULL:
Value = MovingAverage(AverageType.HULL, close, fastLength) - MovingAverage(AverageType.HULL, close, slowLength);
Avg = Average(Value, MACDLength);
}

plot Diff = Value - Avg;
plot ZeroLine = 0;
Value.SetDefaultColor(GetColor(1));
Avg.SetDefaultColor(GetColor(8));
Diff.SetDefaultColor(GetColor(5));
Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Diff.SetLineWeight(3);
Diff.DefineColor("Positive and Up", Color.GREEN);
Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
Diff.DefineColor("Negative and Down", Color.RED);
Diff.DefineColor("Negative and Up", Color.DARK_RED);
Diff.AssignValueColor(if Diff >= 0 then if Diff > Diff[1] then Diff.Color("Positive and Up") else Diff.Color("Positive and Down") else if Diff < Diff[1] then Diff.Color("Negative and Down") else Diff.Color("Negative and Up"));
ZeroLine.SetDefaultColor(GetColor(0));

#plot Min arrows*
def MinArrow = if (Value < Value[1] and Value[1] < Value[2] and Value[2] < Value[3] and Value[-1] > Value and Value < 0)
then 0
else if (Value > Value[1])
then Double.NaN
else Double.NaN;

plot UpArrow = If(MinArrow == 0, Value, Double.NaN);
UpArrow.AssignValueColor(Color.GREEN);
UpArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpArrow.SetLineWeight(1);
UpArrow.HideBubble();

#plot Max arrows*
def MaxArrow = if (Value > Value[1] and Value[1] > Value[2] and Value[2] > Value[3] and Value[-1] < Value and Value > 0)
then 0
else if (Value > Value[1])
then Double.NaN
else Double.NaN;

plot DwnArrow = If(MaxArrow == 0, Value, Double.NaN);
DwnArrow.AssignValueColor(Color.CYAN);
DwnArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DwnArrow.SetLineWeight(1);
DwnArrow.HideBubble();

#plot Max signal(Avg) arrows*
def SignalArrow = if (Avg > Avg[1] and Avg[1] > Avg[2] and Avg[2] > Avg[3] and Avg[-1] < Avg and Avg > 0)
then 0
else if (Avg > Avg[1])
then Double.NaN
else Double.NaN;

plot downSignalArrow = If(SignalArrow == 0, Avg, Double.NaN);
downSignalArrow.AssignValueColor(Color.YELLOW);
downSignalArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
downSignalArrow.SetLineWeight(1);
downSignalArrow.HideBubble();

AddCloud(ZeroLine, Value, Color.RED, Color.GREEN);





#ORDERS*




def exitBad = percentChange < percentLossGoal;


#Sales**
AddOrder(OrderType.BUY_TO_OPEN, UpArrow, open[1], tradeSize, Color.CYAN, Color.CYAN);

AddOrder(OrderType.SELL_TO_CLOSE, DwnArrow, open[1], tradeSize, Color.GREEN, Color.GREEN);

AddOrder(OrderType.SELL_TO_CLOSE, exitBad, open[1], tradeSize, Color.RED, Color.RED);

#ALERTS***
Alert(MinArrow, "CMACD Buy");
Alert(DwnArrow, "CMACD good Sale");
Alert(exitBad, "CMACD Bad stop loss Sale");
 

Slippage

Well-known member
For the order's price you can use open[-1]. That way once the buy/sell condition is met at the close of the current bar it buys at the opening price of the next bar. If your entry/exit markers appear on the wrong bars you can shift them forward or backward, for instance UpArrow[-1]. And then you may also need to shift which opening price is used.
 
Top