Language Tour
Language Tour is a strategy that trades EURUSD and GBPUSD on 15-minute bars. It holds at most 3 open trades (2 per side), reverses on an opposite sign
confirmationssequencetrade managementother bar sizesseveral marketsinside the barrenko, heikin ashi, x-rayuses a library or indicatorcanvastables and dashboardsaccount and historystatefunctions and typessmart moneystatistics and matricessessions and timepending orders
algobarsx 1# Exercises every construct in spec sections 3-16.strategy "Language Tour"markets: EURUSD, GBPUSDbars: 15mevaluate: bar_closemax_open: 3max_open_per_side: 2direction: bothopposite: reversepyramiding: 3min_distance: 20 pipsmax_daily_loss: 3%max_drawdown: 10%trade_only: within sessions london, new_yorkuse indicator "Trend Ribbon" v3 as ribbon (fast: 10, slow: 30)use library "Quant Toolkit" v2 as qtinput fast = 20, label: "Fast length", min: 2, max: 500, group: "Trend"input source = close, label: "Source"input higher_tf = 4h, label: "Higher timeframe"input session = "london", options: ["london", "new_york", "asia"]input risk = 1%, min: 0.1%, max: 5%, step: 0.1%input show_zones = true, group: "Display"input zone_color = blue.fade(70), group: "Display", visible_if: show_zonesconst RISK_CAP = 2%type Level:price: pricetouched: int = 0formed_at: timeenum Regime: trending, ranging, volatilefn swing_strength(len: int) -> number:up = highest(high, len) - closedown = close - lowest(low, len)return (down - up) / atr(14)action fn enter_long(size_risk: percent = 1%) -> bool:buy risk: size_risk, stop: 20 pips, target: 2Rreturn truestate triggers = 0state last_entry: price = nastate regime = Regime.rangingstate levels: list<Level> = []trend_up = ema(close, 50) > ema(close, 200)distance = (source - ema(source, fast)) / atr(14)threshold: number = 1.5h4 = bars(bars: higher_tf)gold = bars(XAUUSD, bars: 15m)gold_atr = atr(14, on: gold)cov = data.coverage(EURUSD, bars: range(10))spread_z = zscore(log(close_of(EURUSD) / close_of(GBPUSD)), 100)first_hour = time_of_day between 08:00 and 09:00recent_high = intrabar(1m).high.max()kelly = qt.kelly_fraction(0.55, 1.8)power = 2 ** 3 ** 2in_window = hour in 8..11if regime == Regime.trending:risk_now = 1%elif regime == Regime.volatile:risk_now = 0.5%else:risk_now = 0.25%for level in levels:if close > level.price:level.touched += 1for i in 0..50:if i > 10:breakcontinuematch regime:Regime.trending: log "trending"Regime.ranging: log "ranging"levels.push(Level(price: high, formed_at: time))levels = levels.filter(l => l.touched == 0).keep_last(50)ranked = levels.sort_by((a, b) => a.price - b.price)confirmations long_setup:trend: trend_upmomentum: rsi(close, 14) > 55volume: volume > sma(volume, 20) * 1.5structure: break_of_structure(direction: up)higher_tf_trend: h4.close > ema(h4.close, 50)ribbon_up: ribbon.uprequire: at least 5sequence liquidity_grab within 30 bars:step sweep: low < lowest(low, 20)[1]step reclaim: close > sweep.highstep retest: low <= reclaim.close and close > reclaim.closereset_if: close < sweep.lowwhen long_setup.passed as long_entry every 4th:buy risk: risk, stop: atr(14) * 1.5, target: 3Rwhen starts(long_setup.passed) skip first 3 max 2 per day cooldown 30m:triggers += 1if triggers % 4 == 0:buy risk: 0.5%, stop: atr(14) * 1.5, target: 3Rwhen liquidity_grab.completed from 08:00 to 11:00 Europe/London:buy risk: 1%, stop: liquidity_grab.sweep.low - 3 points, target: 2R + 5 pips, tag: "breakout":breakeven at: 1R, offset: 2 pipspartial 30% at: 1.5Rpartial 30% at: 2.5Rtrail by: atr(14), after: 2Rexit after: 48 barsexit when: crosses_below(close, ema(close, 20))when crosses_below(close, ema(close, 50)) cooldown 5 bars:sell risk: $200, stop: highest(high, 10) + 2 pips, target: lowest(low, 50)when was(trend_up, within: 5 bars) and held(close > open, for: 3 bars) every bar:buy limit: lowest(low, 5), size: 1 lot, expires: 10 barsbuy stop: high + 2 pips, risk: 0.5%, stop_loss: low - 2 pips, target: 2R, ghost: truesell market: GBPUSD, size: 0.3 lotswhen history.today.pnl < -(2% of account.balance) or account.margin_level < 150%: close_allfor trade in trades.open(tag: "breakout"):if trade.r >= 3 and rsi(close, 14) > 75:close trade, size: 50%for trade in trades.open(side: long):modify trade, stop: trade.entry_pricecancel orders.pending(tag: "grid")on start:log "starting on {market.symbol}"on bar close:log "bar {bar.index}"on fill(order):log "filled {order.size}"on exit(trade):log "{trade.tag} closed at {trade.r:0.00}R after {long_entry.triggers} triggers"on session open "new_york":log "New York is open"on day change:triggers = 0on render(canvas):for z in levels:shape = canvas.path()shape.move_to(z.formed_at, z.price)shape.line_to(canvas.last_bar, z.price)shape.stroke(zone_color, width: 1)canvas.text("{z.touched}x", at: (canvas.last_bar, z.price), align: right)plot ema(close, fast) as fast_line, color: if trend_up then green else red, width: 2plot (high + low) / 2, color: gray, style: stepfill ribbon.fast, ribbon.slow, color: green.fade(80)hline 70, style: dashed, color: #22c55emark arrow_up, at: below, when: crosses_above(close, ema(close, fast)), color: greenlabel "Entry", at: (bar.index, high)line from: (bar.index - 20, lowest(low, 20)), to: (bar.index, lowest(low, 20)), extend: rightbox id: "range", from: (bar.index - 10, highest(high, 10)), to: (bar.index, lowest(low, 10)), color: blue.fade(85)bar_color if close > open then green else redbackground red.fade(90), when: regime == Regime.volatileprofile rows: 24, range: session, side: rightfib from: (bar.index - 50, lowest(low, 50)), to: (bar.index, highest(high, 50))dashboard position: top_right, rows: [["Regime", "{regime}"], ["Triggers", "{triggers}"]]Language Tour is a strategy that trades EURUSD and GBPUSD on 15-minute bars. It holds at most 3 open trades (2 per side), reverses on an opposite signal, adds up to 3 entries in the same direction, keeps at least 20 pips between entries, stops for the day after losing 3%, stops trading after a 10% drawdown and trades only during the London and New York sessions.
It uses the indicator "Trend Ribbon" (version 3) as ribbon, with fast set to 10 and slow set to 30.
It uses the library "Quant Toolkit" (version 2) as qt.
You can change 7 inputs: fast (default 20, shown as "Fast length"), source (default close, shown as "Source"), higher_tf (default 4h, shown as "Higher timeframe"), session (default "london"), risk (default 1%), show_zones (default true) and zone_color (default blue.fade(70)).
It defines the constant RISK_CAP as 2%.
It defines swing_strength(len), which returns a number and the action enter_long(size_risk), which returns true or false.
It remembers triggers, last_entry, regime and levels from one bar to the next.
It calculates trend_up as whether the 50-bar EMA of the close is above the 200-bar EMA of the close, distance as (source minus the EMA of source over fast bars) divided by the 14-bar ATR, threshold as 1.5, h4 as higher_tf bars, gold as XAUUSD 15-minute bars, gold_atr as the 14-bar ATR of gold, cov as the data.coverage (symbol EURUSD, bars the range (size 10)), spread_z as the 100-bar z-score of the logarithm of the close of EURUSD divided by the close of GBPUSD, first_hour as whether the time of day is between 08:00 and 09:00, recent_high as intrabar(1m).high.max(), kelly as qt.kelly_fraction(0.55, 1.8), power as 2 to the power of 3 to the power of 2 and 3 more values.
long_setup passes when at least 5 of these 6 conditions are true: trend (trend_up); momentum (the 14-bar RSI is above 55); volume (volume is above 1.5 × the 20-bar SMA of volume); structure (a bullish break of structure); higher_tf_trend (h4.close is above the 50-bar EMA of h4.close); ribbon_up (ribbon.up).
liquidity_grab completes when these steps happen in order within 30 bars: sweep, when the low is below the previous bar's lowest low of the last 20 bars; then reclaim, when the close is above sweep.high; then retest, when the low is at or below reclaim.close and the close is above reclaim.close. It starts over if the close is below sweep.low.
When long_setup passes (on every 4th time), it buys at market, risking risk of the balance, with a stop 1.5 × the 14-bar ATR from the entry and with a target 3R from the entry.
When long_setup passes becomes true (ignoring the first 3 times, at most 2 times per day and waiting at least 30 minutes between actions), it adds 1 to triggers; it also checks whether triggers modulo 4 is 0 and, if so, buys at market, risking 0.5% of the balance, with a stop 1.5 × the 14-bar ATR from the entry and with a target 3R from the entry.
When liquidity_grab completes (between 08:00 and 11:00 Europe/London time), it buys at market, risking 1% of the balance, with a stop at the low of the sweep step minus 3 points, with a target 2R plus 5 pips from the entry and tagged "breakout"; once open, it moves the stop to breakeven at 1R plus 2 pips, closes 30% at 1.5R, closes 30% at 2.5R, trails the stop by the 14-bar ATR once the trade reaches 2R, exits after 48 bars and exits when the close crosses below the 20-bar EMA of the close.
When the close crosses below the 50-bar EMA of the close (waiting at least 5 bars between actions), it sells at market, risking $200, with a stop at the highest high of the last 10 bars plus 2 pips and with a target at the lowest low of the last 50 bars.
When trend_up at some point within the last 5 bars and the close is above the open for 3 bars in a row (on every bar while it holds), it buys with a limit order at the lowest low of the last 5 bars, with a size of 1 lot and expiring after 10 bars; it also buys with a stop order at the high plus 2 pips, risking 0.5% of the balance, with a stop-loss at the low minus 2 pips, with a target 2R from the entry and kept hidden from the broker until it triggers; it also sells GBPUSD at market, with a size of 0.3 lots.
When today's closed profit or loss is below minus 2% of the account balance or the margin level is below 150%, it closes all trades.
When the script starts, it logs "starting on {market.symbol}".
At every bar close, it logs "bar {bar.index}".
When an order fills, it logs "filled {order.size}".
When a trade closes, it logs "{trade.tag} closed at {trade.r:0.00}R after {long_entry.triggers} triggers".
When the New York session opens, it logs "New York is open".
When a new day begins, it sets triggers to 0.
Whenever the chart is drawn, it goes through each z in levels and sets shape to canvas.path(), moves to a point, draws a line segment, outlines the shape and writes "{z.touched}x" on the chart.
On each bar, it checks whether regime is trending and, if so, sets risk_now to 1%; otherwise, if regime is volatile, sets risk_now to 0.5%; otherwise sets risk_now to 0.25%.
On each bar, it goes through each level in levels and checks whether the close is above level.price and, if so, adds 1 to level.touched.
On each bar, it goes through each i in 0 to 50 and checks whether i is above 10 and, if so, stops the loop; it also moves on to the next item.
On each bar, it checks regime: for trending it logs "trending"; for ranging it logs "ranging".
On each bar, it goes through each trade in open trades tagged "breakout" and checks whether trade.r is at or above 3 and the 14-bar RSI is above 75 and, if so, closes trade (50% of it).
On each bar, it goes through each trade in open trades on the long side and moves the stop to trade.entry_price for trade.
On each bar, it cancels pending orders tagged "grid".
On the chart, it plots the EMA of the close over fast bars as fast_line, plots (the high plus the low) divided by 2, shades between ribbon.fast and ribbon.slow, draws a horizontal line at 70, marks arrow up below the bar when the close crosses above the EMA of the close over fast bars, labels "Entry", draws a line, draws a box, colors the bars, shades the background when regime is volatile, draws a volume profile, draws Fibonacci levels and shows a dashboard.
This description may be incomplete because the script has errors.