Home/Dovee

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 (exit only 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-entry or reEntry = 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. Add for 3 bars to keep it longer

Chart

  • Lines: plot fast as "Fast" blue
  • Band: fill fast, slow green
  • Level: level 70 as "Overbought" red
  • Marks: buy / sell / exit already plot an arrow and the price. Optional extras: arrow up "Breakout" or label "Breakout" for a custom caption, paint green to tint the bar
  • RSI-style pane: put oscillator at the top

Conditions

  • crosses above / crosses below
  • is above / is below
  • close 1 bars ago previous bar (shorthand: close[1]); close rising
  • Candles: bullish, bearish, doji, hammer, engulfing, shootingstar, insidebar, pinbar
  • Clock: monday…sunday, hour, minute (resolved script timezone)
  • else after a when
  • alert "message" — notify without an extra order
  • Symbols work too: rsi(14) > 70, + - * /

Language basics

  • Comments: # or //
  • when is the usual word for a rule (if still works); plot is the usual word for a line (show still works); bodies can use indent, then, or { }
  • Math: round floor ceil sqrt log pow sign abs
  • Price also has time (bar unix seconds), hour, minute. Evaluation is on each closed candle, not ticks.
  • Also: change, replaceMissing (shorthand nz), barssince, valuewhen, mask. na means not available — not enough bars yet (for example ema(50) on the first 49 bars).
  • Colors: green red blue orange purple gray grey white black yellow lime
  • Debug without trading: note "fast=" + fast (or debug)

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 (needs session 9:15 to 15:30)
  • Named range: openingRange = range 9:15 to 9:30 then openingRange high
  • Rolling high/low: highest(high, 20), lowest(low, 20), or donchianupper(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 points follows 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 position
  • entry 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 percent closes half of the quantity still open. targets … split closes 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 inside when. The value carries to the next closed bar. It cannot see future bars. state = 1 is still a normal variable named state.

Risk

  • stop 10 points, stop 2 percent, or stop 2 atr. stop N atr, target N atr, and trail N atr use 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 points closes the whole simulated position. trail 5 points, trail 10 percent, or trail 1 atr closes it when the trail is touched. A fixed stop and a trail together keep the tighter price. breakeven after 10 points or breakeven after 1 percent moves the stop to the average entry after that favorable move. A tighter trail still wins.
  • targets 5, 10, 15 split 40, 30, 30 closes those percents of the opening quantity, one target per bar. The last target closes whatever remains. Without split, the first target touched flattens the position. risk 1 percent sets the initial quantity from initial capital and the stop distance, including a stop at level. A missing stop keeps qty.
  • 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