You already have the setup. You can spot it on a chart in two seconds, you have taken it hundreds of times, and you know roughly how often it pays. Then you sit down to write it out — the exact condition, the exact exit, the exact size — and it dissolves into "well, it depends."
That gap is the entire problem. A discretionary edge lives inside your judgment, where "it depends" is allowed. An algorithm lives inside a specification, where it is not. Every branch has to be resolved in advance by you, because at 03:00 on a Tuesday the machine will not ask you what you meant.
This guide takes you from a fuzzy idea to that specification: a complete, unambiguous rule set covering entry, exit, and risk, precise enough to hand to a coder — or to your own compiler — without a single follow-up question. It stops exactly where the coding starts. What you walk away with is a document, not a file of source code.
Key Takeaways
Building an algorithm is a specification job before it is a coding job — the deliverable of the design stage is a one-page rule set, not source code.
A rule is finished only when two coders would build the same system from it: exact operators, exact numbers, and a stated answer for every execution edge case.
Entry and exit rules decide whether the edge exists; the risk layer — risk per trade, account limits, and the sizing arithmetic — decides whether you are still trading when it shows up.
Table of Contents (43 min read)Contents
What Building Your Own Trading Algorithm Actually Means
Most people picture the coding when they picture building an algorithm. In practice the coding is the short part, and it is the part most likely to be outsourced. The long part — the part that decides whether the finished bot is worth running — is turning a human intuition into a rule that survives contact with a machine.
Algorithmic trading is not "trading with a computer." It is trading according to rules that were fully written down before the trade existed. That definition sets a hard standard for your design work, and it gives you a single test to apply to every sentence you write:
The machine test. If two competent coders read your rule and could produce different trades from it, it is not a rule yet. It is still an opinion.
That test is useful because it converts every vague phrase into a to-do item. "Enter on a strong breakout" fails it — one coder measures strength with a candle body, another with volume, a third with a volatility multiple. "Enter when the bar closes above the highest high of the previous 20 bars by more than 0.5 × ATR(14)" passes it. Same idea; only one of them is executable.
The work has five stages, and they run in order for a reason: an exit rule you write before you know the entry is guesswork, and a position size you calculate before you know the stop distance is impossible.
The design framework
From a trading idea to a code-ready rule spec, in five stages
1
State one testable idea
Write the market behaviour you think you can exploit as a single sentence, with the instrument and the timeframe attached to it.
2
Write the entry rule
Convert that sentence into conditions with exact operators and exact numbers, so the same bar always produces the same decision.
3
Write the exit rules
Define every way the trade can end: target reached, stop hit, time expired, or the original premise invalidated.
4
Add the risk layer
Fix risk per trade, account-level limits, and the arithmetic that turns that risk into an actual position size.
5
Freeze the spec
Assemble everything into one document with no unresolved 'it depends', ready to be coded and then tested.
Each stage takes its input from the one before it — which is why designing the exit before the entry, or the size before the stop, quietly breaks the spec.
Notice what is not on that list: choosing a platform, opening a code editor, or picking a programming language. Those come after. The framework is platform-neutral by design, because the same spec can end up as a MetaTrader robot, a TradingView strategy, or a Python script against an exchange API without a word of it changing.
Start With One Testable Idea, Not a Basket of Indicators
The most common way to ruin an algorithm is to begin with a screen full of indicators and hunt for a combination that looks profitable. That is not strategy design; it is pattern-matching against history, and it produces rules that describe the past instead of predicting anything.
Start from the other end. Write one sentence in this shape:
"In [market], after [observable event], price tends to [behaviour] for [duration], and I can capture it with a trade that [structure]."
A workable example: "In EUR/USD on the 4-hour chart, after price closes above a 20-bar range on an expanding candle, momentum tends to continue for roughly two sessions, and I can capture it with a long that risks a fixed volatility multiple." It names the instrument, the timeframe, the trigger, the expected behaviour, the expected duration, and the trade structure. Every one of those becomes a line in the spec later.
Two properties make an idea worth building on:
It is falsifiable. There is a measurable outcome that would prove it wrong. "Trend following works" is not falsifiable at this resolution. "Breakouts above a 20-bar range on this instrument continue more often than they reverse" is.
It has a plausible mechanism. You can say why the behaviour exists — stops resting above a range, a session handover, a scheduled flow — even if you cannot prove it. Ideas with no mechanism tend to be coincidences you found by looking hard enough.
Keep the condition count low. Two or three entry conditions is a healthy first spec. Every extra condition narrows the sample, and a rule set with eight filters will always look better on historical data and behave worse on new data — the definition of overfitting. You are not trying to build the best-looking backtest; you are trying to build a rule set whose expectancy is real enough to survive being tested honestly.
One mechanism you can explain beats eight filters that only ever agreed with each other on historical data.
How Do You Turn a Trading Idea Into a Precise Entry Rule?
Take your sentence and run it through three passes. Each pass removes a category of ambiguity, and the order matters — resolving execution details before you have named the trigger just produces precise nonsense.
Pass one — name the trigger. Isolate the single observable event that starts the trade. Not the context, not the confirmation: the trigger condition itself. If you cannot point at one bar and say "that is the bar where it fired," you have described a market state rather than a trigger.
Pass two — attach exact numbers and operators. Every indicator gets its full specification: name, period, price source, and the timeframe it is calculated on. Every comparison gets a real operator (>, >=, crosses above) and a real threshold. Every qualitative word gets replaced by arithmetic. "Strong candle" becomes "candle body greater than 0.5 × ATR(14)". "Near the level" becomes "within 0.2 × ATR(14) of the level."
Pass three — resolve the execution questions. This is where most half-finished specs fail, because these questions never come up in discretionary trading — you answer them unconsciously. On paper they have to be explicit:
On which bar is the condition evaluated? At the close of the completed bar, or intrabar as price moves? These produce very different results and very different code.
At what price do you enter? Market on the next bar's open, a limit order at a level, or a stop order above it? Say which, and say what happens if the order is not filled.
What if the condition stays true for several bars in a row? One entry per signal, one entry per range, or pyramiding? Without an answer, the machine takes the trade on every single bar.
What if you already have a position open? Skip the signal, scale in, or reverse?
When is the rule allowed to fire at all? Trading hours, days of the week, and the timezone all of that is measured in.
Answer those five and your entry rule is code-ready. Skip them and your coder will answer them for you, silently, and you will not find out until the results look strange.
Vague vs. specified
The idea as you would say it out loud
“I go long when EUR/USD breaks out strongly from a range.”
“I want a bit of confirmation before I commit.”
“I don’t trade it in the dead hours.”
“I keep the risk small.”
Two coders would build two different systems from this.
The same idea, code-ready
Long when the 4H bar closes above the highest high of the previous 20 closed bars.
And the breakout bar’s body is > 0.5 × ATR(14).
And the bar’s open time is between 07:00 and 19:00 UTC.
And no position is open on this symbol.
Entry: market order, at the next bar’s open.
Risk: 1.0% of balance per trade.
Two coders would build the same system from this.
Precision is not about adding detail — it is about removing every choice the coder would otherwise make on your behalf.
The left column is a trading style. The right column is a specification. Only one of them can be handed over or tested.
Writing Exit Rules: Targets, Stops, and Time Limits
An entry rule with no exit is not half an algorithm — it is not an algorithm at all, because the machine has no way to end what it started. Every trade needs a complete, mutually exclusive set of endings, all of them defined at the moment of entry.
There are four exit families, and a solid spec usually uses three of them:
The stop. Your stop-loss must come from a rule, never from a per-trade decision. Structural ("below the range low minus one tick"), volatility-based ("entry - 1.5 × ATR(14) measured at entry"), or fixed-distance. Volatility-based stops travel across instruments and market regimes better than fixed pip distances, which is why they show up in most cross-market specs.
The target. A take-profit expressed as a multiple of the stop distance keeps the reward-to-risk ratio constant no matter how volatility changes. "Entry + 3 × ATR(14)" is a rule; "around the previous high" is not, until you define which previous high.
The time exit. The most under-used and most valuable of the four. "Close at market after 12 completed bars" caps the opportunity cost of trades that never resolve, and it removes an entire class of dead positions that would otherwise sit there consuming risk budget.
The invalidation exit. The premise itself breaks — price closes back inside the range, or the higher-timeframe condition flips. Use it when the reason for the trade can visibly disappear before the stop is reached.
If you add a trailing stop, specify three things or it is not a rule: what activates it, what distance it trails by, and how often it updates (every bar close, every tick, or at fixed profit steps).
Then handle the one case that quietly corrupts more tests than any other: what happens when the stop and the target are both reachable inside the same bar? Historical bar data cannot tell you which was touched first, so the spec has to state an assumption — the conservative convention is "assume the stop filled first." Write it down. If you leave it out, the tester picks for you, usually optimistically.
Building the Risk and Position-Sizing Layer
The entry and exit rules decide whether your idea has an edge. The risk layer decides whether you are still trading when that edge shows up. Two accounts running an identical rule set with different sizing are not variations of one strategy — they are different strategies, and one of them can be unsurvivable while the other is fine.
This layer has two halves: the limits you set, and the arithmetic that enforces them. Both belong in the spec rather than in your head. And before any of it meets a live account, be clear-eyed about the risks of trading with real capital — a rule set removes emotion from execution, not risk from the market.
Setting risk per trade and a maximum drawdown limit
Start with risk per trade, expressed as a percentage of the current balance or equity rather than a currency amount. A percentage scales with the account automatically and keeps the spec valid after a good month or a bad one. Say which of balance or equity you mean — with several positions open they diverge, and the difference compounds.
Maximum open trades, so a signal firing on six correlated symbols does not become one six-times-sized bet.
Maximum correlated exposure, defined by instrument group rather than by symbol name — three long EUR crosses are largely the same position wearing three tickers.
A maximum drawdown halt: the peak-to-trough decline at which the algorithm stops opening new positions and waits for you. This is your kill switch, and it is the most important line in the risk block, because it is the one that ends a bad run instead of riding it. If you want to see how steep the climb back gets before you pick a number, work out what a given drawdown costs to recover.
Translating risk percentage into position size
The conversion is the same everywhere, even though the units are not:
Position size = (Account balance × Risk %) ÷ (Stop distance × Value per unit of movement)
In forex the stop distance is in pips and the value per unit is the pip value per lot. In futures it is ticks and tick value; in crypto it is the price distance and the coin or contract quantity; in equities it is the price distance and one share. The position-sizing rule in your spec should write out the exact form for your market, including how you round — brokers accept discrete lot steps, and "round down to the nearest 0.01 lots" is a rule your coder needs to be told.
Run your own numbers through it before you commit to a percentage. One percent feels conservative until you see what it becomes on a tight stop.
The sizing rule, live
Risk percentage to position size
The arithmetic your spec has to state. Set the risk you allow per trade and the stop distance your exit rule produces, then read off the size the algorithm should send.
Account balance
$
Risk per trade
Stop distance
pips
Pip value per standard lot
$
Cash at risk per trade
—
Position size
—
Straight losses to reach -20%
—
Halve the stop distance and the position size doubles — which is why sizing has to be arithmetic written into the spec, not a habit kept in your head.
Worked Example: A Fuzzy Breakout Idea Becomes a Full Rule Spec
Here is the whole framework applied end to end, starting from a sentence most traders have said out loud at some point: "I think breakouts work on EUR/USD."
Stage one — make it testable. That sentence has no timeframe, no definition of a breakout, and no expected duration. Rewritten: "On the EUR/USD 4-hour chart, a close above a 20-bar range on an expanding candle tends to continue for roughly two sessions." Now there is something to build.
Stage two — the entry. The range is the highest high of the last 20 closed bars, excluding the current one. "Expanding candle" becomes a body larger than half the 14-period ATR. The decision is made at the bar close and executed at the next bar's open, only when no position is already open, and only inside the London–New York window.
Stage three — the exits. The stop sits 1.5 × ATR below entry, measured at entry and then fixed. The target sits 3 × ATR above it. A time exit closes anything still open after 12 completed bars. If both the stop and the target sit inside the same bar, the stop is assumed to fill first.
Stage four — the risk layer. One percent of balance per trade, one open position at a time on this symbol, and a halt on new entries if drawdown from peak balance exceeds 10%.
Those decisions have a shape on the chart, and it is worth seeing before you read the spec, because the geometry is what makes a still-ambiguous rule obvious:
Worked example
The breakout rule as the machine sees itEUR/USD4H
The signal happens on one bar and the fill happens on the next — a one-bar gap a vague rule hides and a specified rule makes explicit.
Every line on this chart is a sentence in the spec. Nothing about the trade gets decided after it opens.
Stage five — freeze it. Assembled, that is the deliverable. It fits on one page, uses no platform-specific syntax, and answers every question a coder could ask:
The deliverable
pseudocodeeurusd_4h_range_breakout.spec
STRATEGY Range Breakout Continuation
MARKET EUR/USD TIMEFRAME 4H TIMES UTC
DEFINITIONS
rangeHigh = highest high of the last 20 CLOSED bars, excluding current bar
rangeLow = lowest low of the last 20 CLOSED bars, excluding current bar
atr = Average True Range, period 14, on the 4H chart
ENTRY (long)
EVALUATE at bar close
IF close > rangeHigh
AND (close - open) > 0.5 * atr
AND bar open time is between 07:00 and 19:00 UTC
AND open positions on this symbol == 0
THEN buy at market on the open of the NEXT bar
ONE entry per breakout: no re-entry until a bar closes back below rangeHigh
EXIT (long) -- all three armed at entry; the first to trigger wins
stopLoss = entryPrice - 1.5 * atrAtEntry
takeProfit = entryPrice + 3.0 * atrAtEntry
timeExit = close at market after 12 COMPLETED bars
AMBIGUITY RULE: if stopLoss and takeProfit both fall inside one bar's range,
assume stopLoss filled first
RISK
riskPerTrade = 1.0% of account BALANCE (not equity)
positionSize = (balance * 0.01) / (stopDistanceInPips * pipValuePerLot)
rounding = round DOWN to the broker's minimum lot step
maxOpenTrades = 1 on this symbol, 3 overall, 1 per base currency
haltRule = open no new trades while drawdown from peak balance > 10%
SHORT SIDE
Exact mirror of the long rules, using close < rangeLow and inverted exits
OPEN QUESTIONS FOR THE CODER
none
The finished artifact: one page, no platform code, no ambiguity. This is what gets handed over, and what gets tested.
"Open questions for the coder: none" is the line that tells you the design stage is genuinely finished.
Read it back and notice how boring it is. That is the point. A finished spec should read like an instruction manual, not like a trading philosophy.
The Rule-Spec Template You Can Fill In for Your Own Idea
Your idea is not a breakout on EUR/USD, so copy the structure rather than the content. Every line below is a slot in your own document, and the test for each is the same machine test from the start: could two coders read it and disagree?
Work through it against your draft. An unticked item is not a style problem — it is a decision the machine is about to make on your behalf.
Fill-in template
Is your rule spec actually code-ready?
0 / 12
One sentence names the market behaviour you are exploiting, with the instrument and timeframe attached
Every indicator is written with its exact settings: period, price source, and the timeframe it is calculated on
The entry condition uses explicit operators and explicit numbers — no 'strong', 'near', 'confirmed', or 'clean'
The evaluation moment is fixed: which bar closes the decision, and whether it is judged at the close or intrabar
The order type and entry price are stated, plus what happens if the order does not fill
Re-entry behaviour is defined for when the entry condition stays true across several consecutive bars
The stop-loss level comes from a written rule, not from a per-trade judgement call
A target, trailing rule, or invalidation exit is specified, plus a time limit for trades that go nowhere
A precedence rule says which exit wins when the stop and the target sit inside the same bar
Risk per trade is a percentage, and the arithmetic converting it into position size is written out with its rounding
Account-level limits exist: maximum open trades, correlated exposure, and the drawdown level that halts new entries
Trading hours, session filters, and any news or weekend exclusions are stated in one named timezone
★
Checklist complete — you’re cleared to proceed.
Twelve slots. When every one is filled, a coder can build the system without asking you a single question — which is the definition of done at this stage.
Design Mistakes That Sink an Algorithm Before It's Ever Coded
These are failures of design, not of programming. None of them produce an error message — they produce a system that compiles cleanly, tests beautifully, and disappoints in live trading.
Condition stacking. Adding filters until the historical results look good is fitting the rules to the sample. Each new condition should earn its place through a mechanism, not by improving a curve. Keep the entry to two or three conditions and let an out-of-sample test decide whether more are justified.
Thresholds that are not numbers. "High volume", "clean structure", "momentum building" all pass unnoticed while you write and fail the moment someone tries to code them. Search your draft for adjectives; each one is an unfinished decision.
Rules that contradict each other. An entry requiring an expanding range, paired with a filter that skips high-volatility sessions, can produce a spec that almost never fires. Read the conditions together rather than one at a time, and ask when they can all be true simultaneously.
Undefined states. A signal that fires while a position is open, a stop level that lands inside the spread, a gap straight through the stop over a weekend, a partially filled order. Discretionary trading absorbs these instantly. A spec has to name them.
No time dimension. A rule set with no session filter, no maximum holding period, and no calendar exclusions will happily trade the thinnest hour of the week. Time is a condition like any other.
The risk layer bolted on last. If sizing is decided after the strategy "works", you have optimized a version of the system you are not going to trade. Design the stop and the size together with the entry.
Writing the spec for the winning case only. Most of the document should describe what happens when things go wrong, because that is exactly where the machine has no judgment to fall back on.
A cheap and effective final check: hand the document to someone who trades but did not design it, and ask them to describe the next trade it would take. Every place they hesitate is a place your spec is still an opinion.
Does the Same Framework Hold Across Forex, Crypto, Stocks, and Indices?
The framework holds unchanged in every market — idea, entry, exit, risk, spec. What changes is the values inside the blocks, and four of them break a spec quietly if you port it by find-and-replacing the symbol.
The calendar and the clock. Forex runs 24/5, so a trading-session filter is usually mandatory. Crypto runs 24/7, which means there is no session boundary at all and your "daily bar" depends entirely on which cutoff the exchange uses — pin the timezone explicitly. Equities have fixed hours plus opening and closing auctions, and they gap overnight, so a stop can be jumped rather than filled. Index and commodity futures add maintenance breaks and contract rollover dates, which otherwise show up in your data as fake gaps.
The sizing unit. The arithmetic is identical; the denominator is not. Lots and pip value in forex, contracts and tick value in futures, coin or contract quantity in crypto, whole shares in equities. Write the version for your market, including its minimum increment.
The costs the rules have to survive. Spread and swap in forex, funding on crypto perpetuals, commission and borrow cost in equities. A spec with a tight target and no cost assumption is describing a profit the broker collects. State the expected slippage and cost model in the document.
Data continuity. Anything that gaps, rolls, splits, or halts changes what your indicators actually calculate. A 20-bar range measured across a futures rollover is not the range you think it is.
The practical rule: treat a market change as a new strategy that inherits its logic, and re-run the whole spec against it rather than assuming it transfers.
What to Do With Your Finished Rule Spec
You now have a single document — five blocks, one page, no open questions. It is the artifact everything downstream consumes, and it goes to two places.
First, it gets coded. Whether you do that yourself or hire it out, the spec is the input: MQL4 or MQL5 if the destination is MetaTrader, Pine Script if it lives on TradingView, Python if it talks to an exchange API. Turning the strategy design into working MQL4 code is a separate job with its own pitfalls, and it goes far more smoothly when the person doing it is implementing decisions rather than making them. If the destination format is still unfamiliar, it is worth understanding what an Expert Advisor is before you commission one.
Second, it gets tested. A backtest in MetaTrader's Strategy Tester, or the equivalent on your platform, then a forward test on a demo account. Here is the part worth internalizing: most of what looks like a testing problem is actually a specification hole. If the tester produces results you cannot explain, the usual cause is a branch you never resolved — an ambiguous fill, an undefined re-entry, a timezone mismatch — and the fix belongs in the document, not in the code.
Then version it. Give the spec a number, change exactly one rule at a time, and keep the previous version. An algorithm that improves through single documented changes is one you can still reason about a year from now. One that improves by simultaneous tweaking is one you will eventually be afraid to touch.
FAQ
How many rules should a first algorithm have?
Fewer than feels comfortable. Two or three entry conditions, one stop rule, one or two exit rules, and a sizing rule is a complete and testable system. Every additional condition shrinks the number of historical trades your idea can be judged on, and a rule set judged on thirty trades tells you almost nothing regardless of how good the numbers look. Add complexity only when a specific, named failure justifies it.
Do I need to know how to code to design a trading algorithm?
No — and separating the two jobs is often the better workflow. Design is a specification task: precision, completeness, and resolving ambiguity. Coding is a translation task. Plenty of systematic traders write the spec and hand it over. What you do need is enough understanding of how a machine reads instructions to notice when your own sentence is still ambiguous, which is exactly what the machine test gives you.
Should I write the entry rule or the exit rule first?
Entry first, but only just. The entry defines the moment the trade exists, and both the stop distance and the position size are measured from it, so writing exits first means guessing at the anchor. That said, do not treat them as separate projects — draft the entry, immediately draft its exits, and revise the entry if the exits reveal it was underspecified.
What if my edge is genuinely discretionary and resists exact numbers?
Then narrow the scope rather than abandon the project. Take the single most repeatable slice of what you do — one setup, on one instrument, in one session — and specify only that. A narrow algorithm that runs exactly as designed is more useful than a broad one that needs your judgment at runtime, and the act of specifying the narrow slice usually reveals that more of your process is rule-based than you assumed.
How do I know when my rule spec is finished?
When someone else can read it and describe the next trade it would take, in full, without asking you anything. That is the only completion test that matters at this stage. Test results do not tell you the spec is finished — a half-finished spec still produces a backtest, just one that measures decisions your coder made rather than the ones you did.
Sources & Further Reading
Want to go deeper? These independent, authoritative sources shaped this guide — each one is worth reading in full:
The Cross-Market Desk is the SignalBots editorial team for topics that span every market — platform connectors, copy trading, partnership and IB programs, and the general mechanics of trading automation. We research and write the guides that apply no matter what you trade.
Discussions 0
Leave a comment