Dovee
Dovee is an English strategy language — not Pine. Write when-rules, plots, risk, and session filters; Run them on the chart.
Open the chart, then Dovee (Ctrl+E). Write English rules, press Run, and plots appear on the candles. This terminal does not place orders — optionally POST values to your own webhook.
This page is the language tour. Every word and indicator — signature, parameters, return value, example — is in the function reference.
For exact execution guarantees, see the Language Specification v1 and its conformance suite.
What a trader can write
Lengths, factors, and other knobs that a trader will change belong on input lines. buy, sell, and exit already draw an arrow and the fill price (Buy @ 24150.00) — do not add arrow up "Buy", label "Buy", or paint green on the same rule. Use alert only when you want a custom message.
strategy "EMA Cross" long only session 9:15 to 15:15 fastLen = input 9 as "Fast EMA" slowLen = input 21 as "Slow EMA" fast = ema(close, fastLen) slow = ema(close, slowLen) plot fast as "Fast" blue plot slow as "Slow" orange fill fast, slow blue when fast crosses above slow and bullish buy when fast crosses below slow exit alert "Trend flipped" stop 10 points targets 20, 40 split 50, 50
Entries
buy/sell/exit— long, short, flatten (exitonly while in a trade)long only/short only— opposite side becomes an exit- One trade at a time for same-side adds — opposite signals flip direction (buy while short → long, sell while long → short). Write
re-entryorreEntry = input 0 as "Input Re-entry"to allow pyramiding. session 9:15 to 15:15— signals only in that clock window- Resting orders:
buy above X(buy stop),buy below X(buy limit),sell below X(sell stop),sell above X(sell limit). The order waits for the next bar and fills at X, or at the open if the bar gaps past X. Addfor 3 barsto keep it longer
Chart
- Lines:
plot fast as "Fast" blue - Band:
fill fast, slow green - Level:
level 70 as "Overbought" red - Marks:
buy/sell/exitalready plot an arrow and the price. Optional extras:arrow up "Breakout"orlabel "Breakout"for a custom caption,paint greento tint the bar - RSI-style pane: put
oscillatorat the top
Conditions
crosses above/crosses belowis above/is belowclose 1 bars agoprevious bar (shorthand:close[1]);close rising- Candles:
bullish,bearish,doji,hammer,engulfing,shootingstar,insidebar,pinbar - Clock:
monday…sunday,hour,minute(resolved script timezone) elseafter awhenalert "message"— notify without an extra order- Symbols work too:
rsi(14) > 70,+-*/
Language basics
- Comments:
#or// whenis the usual word for a rule (ifstill works);plotis the usual word for a line (showstill works); bodies can use indent,then, or{ }- Math:
roundfloorceilsqrtlogpowsignabs - Price also has
time(bar unix seconds),hour,minute. Evaluation is on each closed candle, not ticks. - Also:
change,replaceMissing(shorthandnz),barssince,valuewhen,mask.nameans not available — not enough bars yet (for exampleema(50)on the first 49 bars). - Colors:
greenredblueorangepurplegraygreywhiteblackyellowlime - Debug without trading:
note "fast=" + fast(ordebug)
Indicators
English names, not Pine ta.*. Same set as the chart library — HMA, Keltner, Donchian, Williams %R, AO, Ichimoku lines, and the rest. ema(9) means close. Anything the trader should be able to change from the script inputs UI — length, factor, oversold level — is an input. Supertrend is ATR length then factor. Color the line with mask, not paint. Multi-line tools: keltnerupper, macdsignal, tenkan. Full list with arguments: Dovee reference.
strategy "Supertrend Stop Target" atrLen = input 10 as "ATR Length" factor = input 3 as "Factor" st = supertrend(atrLen, factor) stUp = mask(st, close is above st) stDown = mask(st, close is below st) plot stUp as "Supertrend Up" green plot stDown as "Supertrend Down" red when close crosses above st buy when close crosses below st sell stop 2 points target 2 points
That flip buys on the Supertrend close. To skip that candle and wait until a later bar breaks its high, remember the level with valuewhen and require barssince(flipUp) > 0. Evaluation is still on the closed breakout candle. Same pattern works for Donchian, previous-day high, or an opening range — any setup where the signal bar is not the fill. Short side: remember low and wait for low crosses below signalLow. Close confirmation: close crosses above signalHigh instead of high.
strategy "Supertrend High Break" long only atrLen = input 10 as "ATR Length" factor = input 3 as "Factor" st = supertrend(atrLen, factor) stUp = mask(st, close is above st) stDown = mask(st, close is below st) plot stUp as "Supertrend Up" green plot stDown as "Supertrend Down" red flipUp = close crosses above st signalHigh = valuewhen(flipUp, high) plot signalHigh as "Signal high" orange when high crosses above signalHigh and barssince(flipUp) > 0 and close is above st and flat buy when long and close crosses below st exit stop 2 atr target 3 atr
The rule above fills at the close of the breakout candle. To fill at the level itself, place a resting order instead. buy above high puts a buy stop at the flip candle's high. It fills on the bar that reaches that price, at that price, or at the open if the bar gaps above it. for 3 bars keeps the order working for three bars; without it the order lasts one bar. A rule that stays true replaces its order with the new level each bar. Stops and targets start on the bar after the fill.
strategy "Supertrend Buy Stop" long only atrLen = input 10 as "ATR Length" factor = input 3 as "Factor" st = supertrend(atrLen, factor) plot st as "Supertrend" green when close crosses above st and flat buy above high for 3 bars when long and close crosses below st exit stop 2 atr target 3 atr
Knobs for the UI: fastLen = input 9 as "Fast EMA". The old word ask still runs (you will see a deprecation warning). If the script has stop, target, or trail, those show as knobs too (Stop Loss, Target, Trail). qty shows as Qty. A split on targets shows TP1 % / TP2 % for how much quantity each target closes.
Multi-timeframe & levels
- Higher timeframe:
trend = ema(close, 50) on 1h— uses the last closed HTF bar only (no look-ahead) - Prior periods:
previous day high,previous week low,previous month close - Developing:
today high,week high,month low - Session levels:
session high(needssession 9:15 to 15:30) - Named range:
openingRange = range 9:15 to 9:30thenopeningRange high - Rolling high/low:
highest(high, 20),lowest(low, 20), ordonchianupper(20)— break the prior bar with[1]so the current candle is not inside its own window - Reusable helper:
function breakout(level, buffer) return close > level + buffer. Parameters may be series, numbers, or true/false. A function cannot call itself. - Timezone:
timezone "Asia/Kolkata"is the one clock for sessions, the opening range, previous day / week / month,on 1D/on 1W/on 1M, and daily loss and daily Sharpe buckets in backtests. Weeks start Monday. Run passes Asia/Kolkata when the script sets no zone. Candle timestamps are left as stored - Trail:
trail 5 pointsfollows the favorable extreme and closes the simulated trade when price comes back to it. The chart line is that same stop
Strategy state (simulated)
Dovee tracks analytical position state for rules and webhooks. This is not a live broker account.
flat/long/short/in positionentry price,bars since entry,profit percent,trade count- Entries fill at the closed bar's close. Stops and targets are checked from the next bar. If one candle touches both, a close beyond one level picks that level; a close between them picks the nearer level, and an equal distance picks the target.
- Partial exit:
exit 50 percentcloses half of the quantity still open.targets … splitcloses each slice of the opening quantity. Trade P&L adds those fills. A finished trade is a win when that sum is positive, a loss when it is negative, and neither when it is zero. A stop, target, trail, or breakeven fills at its level. If the bar opens past the level, it fills at the open. - Persistent value:
state highestSinceEntry = na, then assign it insidewhen. The value carries to the next closed bar. It cannot see future bars.state = 1is still a normal variable named state.
Risk
stop 10 points,stop 2 percent, orstop 2 atr.stop N atr,target N atr, andtrail N atruse N × ATR(14) of the bar each trade opened on.- Dynamic:
stop at entry price - atr(14) * 2,target at entry price + atr(14) * 3. They close the trade. The level set at a bar's close is tested from the next bar. target 20 pointscloses the whole simulated position.trail 5 points,trail 10 percent, ortrail 1 atrcloses it when the trail is touched. A fixed stop and a trail together keep the tighter price.breakeven after 10 pointsorbreakeven after 1 percentmoves the stop to the average entry after that favorable move. A tighter trail still wins.targets 5, 10, 15 split 40, 30, 30closes those percents of the opening quantity, one target per bar. The last target closes whatever remains. Withoutsplit, the first target touched flattens the position.risk 1 percentsets the initial quantity from initial capital and the stop distance, including astop atlevel. A missing stop keepsqty.- Analysis controls:
initial capital 100000,commission 0.03 percent,max trades 3,cooldown 15 minutes
charting.in does not place orders. Create a strategy alert with webhook on, and the saved URL receives the alert message after placeholders fill. Default JSON:
{
"symbol": "{{ticker}}",
"action": "{{strategy.order.action}}",
"qty": {{strategy.order.contracts}}
}Example fill: { "symbol": "NIFTY", "action": "buy", "qty": 0.1 }. qty is the script input (default 1) unless risk N percent sizes the entry. Then qty is that quantity: capital 100000, risk 1 percent, stop 5 points, and entry 100 produce qty 200. A partial exit sends the quantity closed in that slice. Stops and targets are not sent in advance: when one triggers, that hit is its own exit alert. Toasts use: order {{strategy.order.action}} @ {{strategy.order.contracts}} filled on {{ticker}}. New strategy position is {{strategy.position_size}}.
For downstream duplicate protection, a custom JSON alert template can add "signalId": "{{signalId}}". The forwarder persists delivery attempts and sends the signal ID as an Idempotency-Key header. Keyed requests retry network errors, 408/425/429 and 5xx responses with bounded backoff; unkeyed generic forwards are attempted once. Delivery is at-least-once, so your receiver must store and reject IDs it has already processed. A queued response means the delivery is recorded, not that a broker order was placed.
Canonical words
Prefer when (alias if), plot (alias show), exit (alias close as an action), input (deprecated alias ask). Old aliases still run.
Start with these 10
The reference lists every indicator. New traders can begin here:
ema— Follow the trend; fast vs slow EMA crossovers.sma— A slower trend line — support and resistance.rsi— Spot overbought / oversold turns.macdline— Momentum and trend change.supertrend— Stay with the trend; trail with ATR.atr— Measure volatility; size stops as stop 2 atr.bbupper— Upper Bollinger — stretch and mean reversion.bblower— Lower Bollinger — stretch and mean reversion.vwap— Intraday fair value vs the session average.adx— Trend strength (not direction). High ADX = a real trend.
Next: Function reference