SoftwareCompleted

Forex signal research

I built a desktop app to find short-term forex signals, then tested it properly. It won 46% of calls when it needed 55.6%, so I proved the edge wasn't there.

  • Electron
  • JavaScript
  • Node.js
  • Logistic regression
  • Gradient boosting
  • Walk-forward testing
Placeholder for a screenshot of the forex research app showing a price chart and backtest results.

This is the project where I learned the most by being wrong.

The problem

Binary options platforms sell short-term “up or down” calls on currencies and metals. I wanted to know if I could build something that made those calls well enough to win.

The math is simple and brutal. With an 80% payout, you win $0.80 when you’re right and lose $1 when you’re wrong. To break even you need to be right 55.6% of the time.

The solution

I built a desktop app in Electron with a Node.js engine that scanned forex and metals charts and gave short-term calls.

  • It pulled real price data through a chain of data providers, so if one failed it fell back to the next.
  • It scored setups with a weighted set of technical indicators. Despite “AI” in the original name, those were hand-tuned rules, not machine learning.
  • It never placed a trade. That was a rule from the start: before anything touched money, I wanted to know if the signals worked.

How it works

The engine already had a backtester, walk-forward testing (train on one stretch of history, test on the next stretch it has never seen), confidence intervals and calibration checks. I wrote more tools on top to answer one question: do these calls win often enough to make money?

For the wider search later on, I used ten years of daily data on 8 instruments, measured everything after trading costs, and put a gap between training and test windows so nothing leaked. I wrote 23 validation checks for the testing tool itself, including one that made sure my trend-strength indicator matched the engine’s numbers exactly.

Testing

The short-term signals

Pooled across everything, out of sample, the signals won 46% of the time. Worse than a coin flip, and nowhere near 55.6%.

I tried the obvious fixes before giving up:

  • Filter harder: only trade when higher timeframes agree, only high-confidence calls, only trending setups. That got it to around break-even (about 56%), but not by enough to be statistically above it. Filtering mostly just meant fewer trades.
  • Replace the rules with real ML: I trained logistic regression and gradient boosting models to predict direction. Both landed around 51% out of sample.

That second result was the important one. If a properly trained model can’t beat a coin flip either, my indicator weights aren’t the problem. There’s no short-horizon signal there to find. Major currency pairs are some of the most heavily traded markets in the world.

Looking for any edge at all

Strategy Out-of-sample result
Simple trend following, major pairs Sharpe about 0 after costs
Ranking pairs by momentum Lost money at every setting
Carry (earning the interest rate gap) Sharpe 0.56 in training, -0.05 out of sample
200-day trend, only when ADX is 20 or more Sharpe about 1.05, max drawdown 3.3%

Sharpe is return divided by risk. Above 1 is good.

That last row looked great until I checked two things. Its t-statistic was 1.74, and you want at least 2 before calling something real. And when I removed gold and re-ran it on currencies only, it fell apart. Gold was doing almost all the work.

Results

  • The short-term signals don’t work: 46% against 55.6% needed.
  • Real ML models couldn’t do better than about 51%, which points at the market, not the model.
  • There might be a small long-term trend edge in gold. I haven’t proven it.

The bigger finding was about the shape of the bet. Trend following works because of an uneven payoff: you lose small amounts often, and now and then catch a big move that pays for everything. The win rate is usually below 50%, and that’s fine.

A binary option pays the same fixed amount whether the price moves a little or a lot. It cuts off the big wins trend following depends on. So even the one promising idea can’t work as a binary bet. It only makes sense with a normal position, where a big move can pay big.

Add a real screenshot of the app’s backtest view (no account balances)

What I learned

  • Test before you believe. The signals felt right on the chart. The numbers said otherwise, and the numbers win.
  • Out of sample is the only number that counts. Carry looked good in training and died on new data.
  • When a real ML model can’t beat a coin flip, stop tuning. It’s a signal problem.
  • Check what’s doing the work. The “gold trend” result was really just gold.

What’s next

I stopped treating it as a signal app and turned it into a research and journal tool: log ideas, forward-test them on live data without money, and track whether they hold up. The same habits went straight into my Pokémon card scanner, a much messier market where an edge can actually exist.

Demo video

Demo video coming soon: Walking through the backtest that ended the signal app