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

language-tour.abx
1algobarsx 1
2# Exercises every construct in spec sections 3-16.
3strategy "Language Tour"
4markets: EURUSD, GBPUSD
5bars: 15m
6evaluate: bar_close
7max_open: 3
8max_open_per_side: 2
9direction: both
10opposite: reverse
11pyramiding: 3
12min_distance: 20 pips
13max_daily_loss: 3%
14max_drawdown: 10%
15trade_only: within sessions london, new_york
16
17use indicator "Trend Ribbon" v3 as ribbon (fast: 10, slow: 30)
18use library "Quant Toolkit" v2 as qt
19
20input fast = 20, label: "Fast length", min: 2, max: 500, group: "Trend"
21input source = close, label: "Source"
22input higher_tf = 4h, label: "Higher timeframe"
23input session = "london", options: ["london", "new_york", "asia"]
24input risk = 1%, min: 0.1%, max: 5%, step: 0.1%
25input show_zones = true, group: "Display"
26input zone_color = blue.fade(70), group: "Display", visible_if: show_zones
27
28const RISK_CAP = 2%
29
30type Level:
31price: price
32touched: int = 0
33formed_at: time
34
35enum Regime: trending, ranging, volatile
36
37fn swing_strength(len: int) -> number:
38up = highest(high, len) - close
39down = close - lowest(low, len)
40return (down - up) / atr(14)
41
42action fn enter_long(size_risk: percent = 1%) -> bool:
43buy risk: size_risk, stop: 20 pips, target: 2R
44return true
45
46state triggers = 0
47state last_entry: price = na
48state regime = Regime.ranging
49state levels: list<Level> = []
50
51trend_up = ema(close, 50) > ema(close, 200)
52distance = (source - ema(source, fast)) / atr(14)
53threshold: number = 1.5
54h4 = bars(bars: higher_tf)
55gold = bars(XAUUSD, bars: 15m)
56gold_atr = atr(14, on: gold)
57cov = data.coverage(EURUSD, bars: range(10))
58spread_z = zscore(log(close_of(EURUSD) / close_of(GBPUSD)), 100)
59first_hour = time_of_day between 08:00 and 09:00
60recent_high = intrabar(1m).high.max()
61kelly = qt.kelly_fraction(0.55, 1.8)
62power = 2 ** 3 ** 2
63in_window = hour in 8..11
64
65if regime == Regime.trending:
66risk_now = 1%
67elif regime == Regime.volatile:
68risk_now = 0.5%
69else:
70risk_now = 0.25%
71
72for level in levels:
73if close > level.price:
74level.touched += 1
75
76for i in 0..50:
77if i > 10:
78break
79continue
80
81match regime:
82Regime.trending: log "trending"
83Regime.ranging: log "ranging"
84
85levels.push(Level(price: high, formed_at: time))
86levels = levels.filter(l => l.touched == 0).keep_last(50)
87ranked = levels.sort_by((a, b) => a.price - b.price)
88
89confirmations long_setup:
90trend: trend_up
91momentum: rsi(close, 14) > 55
92volume: volume > sma(volume, 20) * 1.5
93structure: break_of_structure(direction: up)
94higher_tf_trend: h4.close > ema(h4.close, 50)
95ribbon_up: ribbon.up
96require: at least 5
97
98sequence liquidity_grab within 30 bars:
99step sweep: low < lowest(low, 20)[1]
100step reclaim: close > sweep.high
101step retest: low <= reclaim.close and close > reclaim.close
102reset_if: close < sweep.low
103
104when long_setup.passed as long_entry every 4th:
105buy risk: risk, stop: atr(14) * 1.5, target: 3R
106
107when starts(long_setup.passed) skip first 3 max 2 per day cooldown 30m:
108triggers += 1
109if triggers % 4 == 0:
110buy risk: 0.5%, stop: atr(14) * 1.5, target: 3R
111
112when liquidity_grab.completed from 08:00 to 11:00 Europe/London:
113buy risk: 1%, stop: liquidity_grab.sweep.low - 3 points, target: 2R + 5 pips, tag: "breakout":
114breakeven at: 1R, offset: 2 pips
115partial 30% at: 1.5R
116partial 30% at: 2.5R
117trail by: atr(14), after: 2R
118exit after: 48 bars
119exit when: crosses_below(close, ema(close, 20))
120
121when crosses_below(close, ema(close, 50)) cooldown 5 bars:
122sell risk: $200, stop: highest(high, 10) + 2 pips, target: lowest(low, 50)
123
124when was(trend_up, within: 5 bars) and held(close > open, for: 3 bars) every bar:
125buy limit: lowest(low, 5), size: 1 lot, expires: 10 bars
126buy stop: high + 2 pips, risk: 0.5%, stop_loss: low - 2 pips, target: 2R, ghost: true
127sell market: GBPUSD, size: 0.3 lots
128
129when history.today.pnl < -(2% of account.balance) or account.margin_level < 150%: close_all
130
131for trade in trades.open(tag: "breakout"):
132if trade.r >= 3 and rsi(close, 14) > 75:
133close trade, size: 50%
134
135for trade in trades.open(side: long):
136modify trade, stop: trade.entry_price
137
138cancel orders.pending(tag: "grid")
139
140on start:
141log "starting on {market.symbol}"
142
143on bar close:
144log "bar {bar.index}"
145
146on fill(order):
147log "filled {order.size}"
148
149on exit(trade):
150log "{trade.tag} closed at {trade.r:0.00}R after {long_entry.triggers} triggers"
151
152on session open "new_york":
153log "New York is open"
154
155on day change:
156triggers = 0
157
158on render(canvas):
159for z in levels:
160shape = canvas.path()
161shape.move_to(z.formed_at, z.price)
162shape.line_to(canvas.last_bar, z.price)
163shape.stroke(zone_color, width: 1)
164canvas.text("{z.touched}x", at: (canvas.last_bar, z.price), align: right)
165
166plot ema(close, fast) as fast_line, color: if trend_up then green else red, width: 2
167plot (high + low) / 2, color: gray, style: step
168fill ribbon.fast, ribbon.slow, color: green.fade(80)
169hline 70, style: dashed, color: #22c55e
170mark arrow_up, at: below, when: crosses_above(close, ema(close, fast)), color: green
171label "Entry", at: (bar.index, high)
172line from: (bar.index - 20, lowest(low, 20)), to: (bar.index, lowest(low, 20)), extend: right
173box id: "range", from: (bar.index - 10, highest(high, 10)), to: (bar.index, lowest(low, 10)), color: blue.fade(85)
174bar_color if close > open then green else red
175background red.fade(90), when: regime == Regime.volatile
176profile rows: 24, range: session, side: right
177fib from: (bar.index - 50, lowest(low, 50)), to: (bar.index, highest(high, 50))
178dashboard position: top_right, rows: [["Regime", "{regime}"], ["Triggers", "{triggers}"]]
What this script says

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.

Try this in the Terminal. AlgoBars is free: $0 a month, no card needed.

Create my free account