Skip to content
AlgoBot Pro
A software team for traders

Your strategy, written as code you can rely on.

We build MetaTrader expert advisors, TradingView indicators, and the systems real money runs on. Fixed price within 48 hours. Full source, always — no lock-in.

Outcome model240 paths · 260 / 260 tradesModel, not a track record
breakeven at 33.3%
Median
2.41×
5th pct
1.63×
95th pct
3.45×
Median max DD
−9.6%

Losing two trades out of three is still a winning system, as long as each win is worth two losses. Drag the slider until it isn’t.

Stack
MQL5 · Pine v6 · TypeScript · Python
Handover
Full source, always
Reach
English, Persian and Arabic · any timezone
Free static audit

Paste your Expert Advisor. Find out what it actually does.

A static pass over MQL4, MQL5 and Pine looking for the handful of mistakes that never show up in the Strategy Tester and always show up on a live account. It reads your code the way we would on the first pass of a paid audit.

Nothing is uploaded. The analysis runs entirely inside your browser.

Static analyserMQL detected3 critical6 warning1 note
FindingsStays in your browser
  • criticalline 33

    Lot size is never normalised to the broker's volume step

    The broker rejects any volume that is not a multiple of its step, so the order simply never opens. The Strategy Tester checks the step too, but only for the one symbol and broker you test on — so a backtest stays clean whenever the formula happens to land on that step, and the same code fails on a symbol or broker with a coarser one.

    Fix: Read SYMBOL_VOLUME_STEP, floor the lot to a multiple of it, then clamp between SYMBOL_VOLUME_MIN and SYMBOL_VOLUME_MAX before sending.

    OrderSend(Symbol(), OP_BUY, currentLot, Ask, 3, sl, tp, "buy", 0, 0, clrGreen);
  • criticalline 33

    Stop loss and take profit are set without checking the stops level

    Every broker refuses stops placed closer to price than its minimum distance. On a quiet pair it works; the first time the spread widens, the order is rejected and the position runs unprotected.

    Fix: Read SYMBOL_TRADE_STOPS_LEVEL and push the stop out to at least that distance, then check SYMBOL_TRADE_FREEZE_LEVEL before modifying an open position.

    OrderSend(Symbol(), OP_BUY, currentLot, Ask, 3, sl, tp, "buy", 0, 0, clrGreen);
  • criticalline 44

    Position size is multiplied after a loss

    This is not a bug, it is a choice — but it is the choice that produces a beautiful equity curve and then removes the account in one losing streak.

    Fix: If it is deliberate, cap the number of steps and the maximum exposure, and test against the worst losing streak in the data rather than the average.

    currentLot = currentLot * Multiplier;
  • warningline 27

    Division with no guard against a zero denominator

    Indicator buffers can hold zero before they have enough bars, and a flat or single-tick bar has no range. Divide by that and, depending on a compiler setting, the program either stops with "zero divide" or carries on with infinity — and the first trades after a restart are placed on nonsense values.

    Fix: Check the denominator is meaningfully above zero before dividing, and return early when the indicator is not ready.

    double ratio = (fast - slow) / atr;
  • warningline 31

    Point is used without adjusting for 5-digit and 3-digit brokers

    The same input means ten times the distance depending on the broker. A 40-pip stop becomes a 4-pip stop, which the market takes out immediately.

    Fix: Derive a pip from _Point and _Digits: multiply by 10 when _Digits is 3 or 5, and use that everywhere instead of raw Point.

    double sl = Bid - StopLoss * Point;
  • warningline 33

    Orders are sent without checking that trading is permitted

    When AutoTrading is off, the account is read-only, or the terminal is still connecting, every send fails silently and the robot looks like it simply stopped working.

    Fix: Guard the send with TERMINAL_TRADE_ALLOWED and MQL_TRADE_ALLOWED, and log the reason when it is refused.

    OrderSend(Symbol(), OP_BUY, currentLot, Ask, 3, sl, tp, "buy", 0, 0, clrGreen);
  • warningline 33

    The result of the order send is discarded

    A rejected order is indistinguishable from a filled one. The robot carries on believing it is in a position that does not exist, and the next decision is built on a false state.

    Fix: Capture the return value, check the retcode, and read GetLastError on failure. Decide explicitly whether to retry or stand down.

    OrderSend(Symbol(), OP_BUY, currentLot, Ask, 3, sl, tp, "buy", 0, 0, clrGreen);
  • warningline 33

    Orders are sent without checking that the account can afford them

    The order is rejected for insufficient margin, and whatever your code does next assumes a position that does not exist. Checking funds before a trade is one of the checks MetaQuotes lists for EAs published in its Market.

    Fix: Call OrderCalcMargin for the intended volume and compare it to AccountInfoDouble(ACCOUNT_MARGIN_FREE) before sending. Decide explicitly what to do when it does not fit — skipping the trade is a decision, silently failing is not.

    OrderSend(Symbol(), OP_BUY, currentLot, Ask, 3, sl, tp, "buy", 0, 0, clrGreen);
  • warningline 36

    Floating point values compared with equality

    Two prices that look identical on screen differ in the last bits, so the branch never runs. It fails silently and intermittently, which is the hardest kind of bug to find months later.

    Fix: Compare with a tolerance: MathAbs(a - b) < _Point / 2, or normalise both sides to the symbol's digits first.

    if(AccountProfit() == 0.0)
  • noteline 37

    Sleep is called inside the tick handler

    While OnTick is asleep the EA handles nothing else, and ticks that arrive meanwhile are not queued; any price read before the pause — and MQL4's Ask and Bid until RefreshRates — is stale when it wakes. In the Strategy Tester, Sleep costs no real time, so the backtest never shows what the pause costs live.

    Fix: Use a timer event or a timestamp check instead of blocking, so the handler always returns quickly.

    Sleep(500);

Is your own EA or indicator doing the same?

Send it to us. We read it line by line and come back with a fixed price within 48 hours.

Get yours checked
A heuristic first pass, not a substitute for reading the code. It can miss things, and it can flag something you have handled in a way it does not recognise. Every finding names a line so you can check it yourself.Get a real audit →
Free code check — all 31 rules
Capabilities

One team builds the whole column.

We are a software team, and the trading terminal is only where our work starts. What we are best at is software that handles money and time correctly: the robot that trades, the data it reads, the dashboard that shows what it did, and the app that wakes you when something is wrong. One team builds all of it, so nothing gets lost where the pieces meet.

Expert advisors, indicators and screeners

Robots and indicators that keep working after the backtest: lot size calculated correctly, broker limits respected, and a recovery path for the disconnects that stop amateur code.

  • MQL4
  • MQL5
  • PINE V6
  • CTRADER

Market data and trade records

Collecting, cleaning and storing price data; logging every order; checking the records against the broker’s. The quiet layer that decides whether the number on your screen can be trusted.

  • TYPESCRIPT
  • PYTHON
  • POSTGRES
  • REDIS

Connecting systems

Broker APIs, payment gateways, CRMs and messaging apps, wired together so a failed step can be run again safely and you can see what happened.

  • REST
  • WEBSOCKET
  • FIX
  • QUEUES

Dashboards and client portals

A page that shows what the system did today, a portal for your clients, an internal tool for your team. Fast on a weak connection, and correct in English, Persian and Arabic.

  • NEXT.JS
  • REACT
  • NODE
  • TAILWIND

Mobile and desktop apps

Android, iOS and desktop apps for the systems above: your portfolio in your pocket, and an alert that actually arrives. Built on the same core, so the rules cannot drift between platforms.

  • KOTLIN
  • SWIFT
  • REACT NATIVE
  • ELECTRON
Broker / exchange

Where the system ends and real money begins. Everything above it is ours to get right.

What keeps a system standing is rarely the idea. It is whether somebody decided, in advance, what happens when the connection drops at 02:14.

Those decisions are the specification. It is written before the code, and the price is attached to it — so you know exactly what you are buying before we start.

Repaint demonstrator

Watch a backtest invent trades that never existed.

The same indicator, the same candles, drawn two ways. One is what the chart shows you today. The other is what you could actually have known at the time. Flip the switch and watch the line move.

Higher-timeframe crossM15 · HTF 2H · EMA 4Sample data
Higher-timeframe average
Real entry
Entries in the backtest
10

What the strategy tester counts, and what a vendor screenshots.

Entries you could take
2

Signals that existed at the moment they appeared, on closed data only.

Entries that never existed
8

Pure invention. Every one of these is profit in the report and nothing in the account.

The higher-timeframe bar has not closed yet, but on history the chart already knows how it ends — so the average is drawn in a position nobody could have seen. Two lines of Pine cause this, and two lines fix it: a [1] offset on the requested expression, together with lookahead = barmerge.lookahead_on. That is the whole difference between a report you can trade and a report you cannot. How to test your own indicator →

Simulator

Win rate is not the thing that decides it.

This runs two hundred and forty Monte Carlo paths in your browser, live. Move the sliders. A 65% win rate at 0.5R loses money; a 40% win rate at 3R does not. Position sizing only decides how violently you get there.

Strategy Monte Carlo240 pathsPositive edge
Median path
Median path
90% of outcomes
90% of outcomes
Starting capital
Starting capital

Expectancy below zero means no position size saves it. That is the whole argument.

Expectancy
+0.35R
Median
2.68×
5th pct
1.82×
95th pct
4.19×
Median max DD
−9.7%
Lost half
0%
Worst streak
15
Paths
240

A deliberately simple model: fixed-fractional sizing, one R per trade, no correlation between trades, no slippage or commission. It is here to show the shape of the maths, not to price your strategy.

Code

What the corrected version looks like.

The same failure points the analyser looks for, written the way they should be: broker-constraint handling, a repaint guard that holds, and a retry that cannot double your position. This is the standard every delivery is held to.

Risk-based position sizing, normalised to every broker constraint.

//--- Risk-based lot size, normalised to every broker constraint.
//--- The three lines most EAs skip are exactly why they die on a
//--- live account and never in the tester.
double LotForRisk(const double riskPercent, const double stopPoints)
{
   if(stopPoints <= 0.0) return(0.0);

   const double equity    = AccountInfoDouble(ACCOUNT_EQUITY);
   const double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   const double tickSize  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   if(tickValue <= 0.0 || tickSize <= 0.0) return(0.0);

   const double lossPerLot = (stopPoints * _Point / tickSize) * tickValue;
   if(lossPerLot <= 0.0) return(0.0);

   double lots = (equity * riskPercent / 100.0) / lossPerLot;

   //--- step / min / max. Without these you get "invalid volume"
   //--- at 02:00 and the robot silently stops trading.
   const double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   const double lo   = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   const double hi   = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);

   lots = MathFloor(lots / step) * step;
   lots = MathMax(lo, MathMin(hi, lots));

   return(NormalizeDouble(lots, (int)MathRound(-MathLog10(step))));
}
Services & indicative pricing

Priced before it starts, not after.

Every engagement is quoted as a fixed price against a written specification. If the spec does not change, the price does not change.

Priced before it starts, not after.
ServiceFromDeliveryPlatformsGet a quote for this
Expert Advisors for MetaTrader450 USD7–21 daysMetaTrader 4MetaTrader 5Detail →
TradingView indicators & screeners180 USD3–10 daysTradingViewPine v6Detail →
Strategy to code300 USD5–14 daysMetaTrader 4MetaTrader 5TradingViewDetail →
Web applications & client portals1200 USD2–6 weeksNext.jsTypeScriptPostgreSQLDetail →
Audit & repair120 USD2–5 daysMQL4MQL5PineTypeScriptDetail →

Indicative starting prices. The quote you receive is fixed and itemised against the written specification.

All services in full →
Method

Four steps, in this order, every time.

You know what you are paying for before we start typing. The order matters: every step exists to make the next one cheaper.

  1. You describe it

    In plain language, a screenshot, or a voice note. You do not need to know what a pointer is. If the rules contradict each other, we tell you before we go further — that conversation is free.

  2. We write the specification

    Every rule, every edge case, every thing the system will deliberately not do. You approve it. This document is what the fixed price is attached to, and it is what protects both of us.

  3. Build and test

    Built against the spec, then tested on real data — tick data for trading systems, production-shaped data for everything else. You see the test output, not a claim about it.

  4. Handover

    Source code, build instructions, parameter documentation, and a walkthrough call. Thirty days of fixes for anything that does not match the specification.

Terms of engagement

What you are promised, in writing.

These are not marketing lines. Each one goes into the engagement agreement exactly as written here, and you get that agreement before you pay anything.

  1. Fixed price

    Quoted against the approved specification. If the spec does not change, the invoice does not change.

  2. Full source, always

    You receive the source code and the right to modify it. No licence server, no time bomb, no dependency on us.

  3. Staged payment

    Part on specification approval, the rest on delivery. You never pay in full for something you have not seen run.

  4. 30 days of fixes

    Anything that does not match the specification is corrected at no cost for thirty days after handover.

  5. Your confidentiality

    NDA signed before you describe the strategy. Your rules are never reused, resold, or shown as an example.

  6. An honest no

    If what you want cannot work, you hear it in the first reply — before an invoice exists, not after.

Who you are talking to

A small team, led by a trader.

AlgoBot Pro is a small software team. The person who reads your message is the person who writes the code, and he trades himself — so the first questions you get are a trader’s questions: which broker, which session, what should happen when the connection drops. You do not have to take our word on quality: the analyser is open source, the code checker runs in your own browser, and every number on the Work page comes from a measurement.

Open source
31 rules, MIT licence
We reply in
English · Persian · Arabic
Reply
Within one working day
Source code
Yours, in full

Describe it badly. We will ask the right questions.

Five questions is usually enough for a fixed quote. You do not need a specification, a diagram, or the right vocabulary — that part is our job.

Start a projectTelegram