Alert on your own condition
In this tutorial we will work out where the close crosses above a moving average, mark those bars on the chart, and raise an alert on them.
We will use alert rather than alertcondition, because alert is the one output-shaped function
that may be called inside a condition, which is what “alert me when this happens” needs.
Each step below is a whole script. Replace what is in the editor, and check it.
Step 1: draw the average
indicator("Cross above the average", "cross", true)
length = input.int(20, "Length", 1, 200)
float avg = talib.sma(close, length)
plot(avg, title = "Average", color = color.gray)A grey line is drawn across the price bars, and Length is a setting on the script.
Step 2: work out the condition
A cross above the average is two facts about one bar: this bar’s close is above the average, and the
previous bar’s close was not. We write both and join them with and. close[1] is the close of the
previous bar.
indicator("Cross above the average", "cross", true)
length = input.int(20, "Length", 1, 200)
float avg = talib.sma(close, length)
bool crossedUp = close > avg and close[1] <= avg
plot(avg, title = "Average", color = color.gray)The chart has not changed. crossedUp is a bool for every bar and nothing reads it yet.
Step 3: see the condition on the chart
Before alerting on a condition, look at it. plotshape takes a condition as its first argument and
puts a mark on the bars where the condition holds.
indicator("Cross above the average", "cross", true)
length = input.int(20, "Length", 1, 200)
float avg = talib.sma(close, length)
bool crossedUp = close > avg and close[1] <= avg
plot(avg, title = "Average", color = color.gray)
plotshape(crossedUp, title = "Cross", shape = shape.triangleup, location = location.belowbar, color = color.green, size = size.tiny)Check it. A mark appears below each bar where the close crossed above the grey line, in the shape, position, size and colour we named. Change Length and the marks move with it.
This step matters because it is the last one with a visible result. Do not go on until the marks are where you expect them.
Step 4: raise the alert
indicator("Cross above the average", "cross", true)
length = input.int(20, "Length", 1, 200)
float avg = talib.sma(close, length)
bool crossedUp = close > avg and close[1] <= avg
if crossedUp {
alert("Close crossed above the average")
}
plot(avg, title = "Average", color = color.gray)
plotshape(crossedUp, title = "Cross", shape = shape.triangleup, location = location.belowbar, color = color.green, size = size.tiny)Check it. The script validates, the marks are still there, and nothing else happens — which is the expected result.
Here is why. alert fires only on realtime bars, only when the script is running as an alert, and
at most once per bar. On historical bars it does nothing, so it raises nothing as the script works
through the chart’s history. The marks from step 3 are how you see where it would have fired.
Note where the two calls sit. alert is inside the branch; plotshape is at the top level. Moving
plotshape inside the branch would be rejected, and this is the one place where the two kinds of
call part company.
Step 5: arm it
Raising the alert is the whole of the script’s part. Whether the script is running as an alert, and
where the message is delivered, are set on the platform rather than in the language. Until the
script runs as an alert on a realtime bar, alert does nothing.
What we built
Four lines of calculation, one alert and one marker. The message we passed is a fixed string, but
alert accepts a message that changes from bar to bar, so it can carry what the script worked out.
Next
- Alerts — the full contract of both alert functions, and when to prefer
alertcondition. - Webhooks for algo trading — where a raised alert can be delivered.
- Text and markers — the shapes, sizes and positions a mark can take.