#1 RealTest Backtests
Supercharge Your Trading Now
Reduce drawdown, build diversification, or speed up your development time.
RealTest has no crypto data source and does not need one, because its CSV importer takes exchange exports directly. Yahoo covers the majors free under tickers like BTC-USD, while a universe comes from the exchange through CCXT as CSV. The parts people get wrong are fees, which are a percentage of notional rather than a dollar amount, and funding on perpetuals, which is a real cash flow that never appears in an OHLCV file.
RealTest has no crypto data source. There is no exchange to select in the import dialog, and there will not be one. What it has instead is a CSV importer, which turns out to be enough, because every crypto exchange will hand you history as CSV and the CSV path in RealTest is a first-class citizen rather than a fallback.
There are two routes in, and the right one depends on whether you are testing a handful of majors or an actual universe.
Yahoo carries the large coins under ticker names like BTC-USD, ETH-USD and SOL-USD, and RealTest imports them the same way it imports a stock.
Import:
DataSource: Yahoo
IncludeList: SPY
IncludeList: BTC-USD, ETH-USD, SOL-USD {"InCRYPTO"}
StartDate: Earliest
EndDate: Latest
SaveAs: MainCrypto.rtd
The braces create a named list, so InList("InCRYPTO") is true for those three symbols and you can keep an equity benchmark like SPY in the same file without it entering trades. This route costs nothing and takes a minute, and for a system that trades Bitcoin and Ethereum it is genuinely sufficient. Its limits are the same ones that apply to Yahoo data anywhere, which is a small set of instruments and no way to reach the ones that died.
For a universe you pull history from the exchange yourself, usually through CCXT, and write it to CSV. RealTest reads either one file per symbol or a single file containing many symbols, and for crypto the single-file form is easier to keep current.
Import:
DataSource: CSV
CSVFields: Date,Symbol,Open,High,Low,Close,Volume
CSVFile: C:\CryptoData\binance_daily.csv
StartDate: Earliest
EndDate: Latest
SaveAs: crypto.rtd
The file needs a Symbol column when you use CSVFile, and the column names in CSVFields have to match the order in your file. If you instead keep one file per instrument, swap CSVFile for DataPath pointing at the folder, and name each file after its symbol. Both forms accept the same field names, of which only Date and Close are strictly required.
Two details save an afternoon. Dates are parsed as month-day-year unless you set CSVDateFmt: DMY, and exchange exports are frequently day first. And crypto symbols contain a slash, so a comparison in a formula looks like Symbol = $BTC/USDT rather than the bare ticker you would use for a stock.
Stock backtests use a dollar commission with a minimum. Crypto exchanges charge a fraction of notional and split it by whether you took liquidity or provided it. RealTest expresses that directly, because Commission is a formula rather than a number, and FillValue is the dollar size of the position at entry.
Parameters:
MakerFee: 0.0002 // limit orders that rest on the book
TakerFee: 0.0005 // market orders that cross the spread
Strategy: CryptoMR
Commission: TakerFee * FillValue
Set those two values to your own fee tier rather than the example, and use the taker rate unless your entries genuinely rest as limit orders. Getting this wrong is not a rounding error in a strategy that turns over daily. A system taking two hundred round trips a year at market pays a fifth of a percent every time it moves, which compounds into a difference that decides whether the edge exists.
If you are testing perpetual futures rather than spot, funding is a real cash flow that arrives several times a day and can be larger than your edge in a crowded trade. It is not in the OHLCV file, so it has to come in separately, and the way RealTest handles this is neat. Import the funding history as its own symbol in a second CSV, then read it from any formula with Extern.
Import:
DataSource: CSV
CSVFields: Date,Symbol,Open,High,Low,Close,Volume
CSVFile: C:\CryptoData\binance_daily.csv
DataSource: CSV
CSVFields: Date,Symbol,Close
CSVFile: C:\CryptoData\daily_funding_rates.csv
SaveAs: crypto.rtd
Data:
FundingRate: Extern($FUNDING_RATE, C)
Multiple DataSource blocks combine into one data file, so the funding series ends up alongside the price series and Extern pulls its value on each bar regardless of which instrument the formula is currently evaluating. From there you can charge it against a position, filter entries when funding is extreme, or simply plot it to see how much of a backtested return was really a funding subsidy.
Equities have a closing auction. Crypto does not, so a daily bar is a convention someone chose, almost always the UTC midnight boundary. That is fine as long as every file in your universe uses the same convention. Mixing an exchange export cut at UTC with a source cut at New York time produces bars that disagree by hours, which shows up as an edge that appears and disappears depending on which symbols are in the test.
Survivorship bias is worse here than in equities. Exchanges delist pairs regularly, and a token that stops trading simply stops appearing in the export. Build a universe from the pairs Binance lists today and backtest it over five years and you have selected for the tokens that survived a period in which most did not. The fix is the same as it is for stocks, which is to keep the delisted pairs in your CSV rather than rebuilding the list each time you download. If you are new to why that matters, it is the second of the five backtesting mistakes that fake an edge.
A stock has one official closing price. A coin has as many prices as there are venues, and they differ enough to matter for a strategy trading small moves. Whatever exchange you intend to trade on is the exchange your history should come from, and testing on Binance data while executing on Coinbase introduces a gap that no cost assumption models.
They track each other and they are not the same thing. Perpetuals carry funding, allow leverage, and can dislocate from spot exactly when your strategy is most exposed. A backtest built on spot candles that is then traded on perps is testing something adjacent to what you are doing.
Pull one symbol first, BTC/USDT daily, and import it alone. Check the first and last bar and the row count before writing a strategy, since a truncated download looks identical to a working one until the results make no sense. Then add the rest of the universe, and only after that add funding.
Keep the download and the import as separate steps you can run independently. The download is slow and rate-limited, the import takes seconds, and mixing them means waiting for the exchange every time you want to change a field mapping.
If you would rather not write the downloader, our Python code to download crypto data from Binance with CCXT produces files in the shape the import above expects, and the free crypto CSV data for spot and futures lets you skip the download entirely for a first test.
Once the data is in, the question becomes what to test. If you would rather read than download, the SetupAlpha Substack is where the longer research goes, including the academic papers behind several of these systems. It is free and the archive is large enough to keep you busy.
Yes, though not through a dedicated crypto data source. RealTest imports crypto either from Yahoo, which carries the majors under tickers such as BTC-USD, or from CSV files exported from an exchange. The CSV path is a full feature rather than a fallback, so a universe of exchange pairs imports as cleanly as stocks do.
Export the history to CSV, usually via CCXT, then use an Import section with DataSource set to CSV, a CSVFields line matching your column order, and CSVFile pointing at the file. A multi-symbol file needs a Symbol column. RealTest writes the result to a data file that your strategies then read.
For crypto the single multi-symbol file is usually easier to keep current, since one refresh updates the whole universe. Use CSVFile for that form and DataPath for the folder form, where each file has to be named after its symbol.
Because RealTest parses dates as month-day-year by default and most exchange exports are day first. Adding CSVDateFmt set to DMY fixes it. The symptom is usually a data file that imports without error but contains far fewer bars than expected.
As a percentage of position value rather than a dollar amount. Commission is a formula, and FillValue holds the dollar size of the position at entry, so a taker fee is written as your rate multiplied by FillValue. Use the taker rate unless your entries genuinely rest as limit orders.
A maker order rests on the order book and adds liquidity, usually at a lower fee. A taker order crosses the spread and removes liquidity, at a higher one. A backtest that assumes maker fees while the live strategy sends market orders understates costs on every single trade.
Import the funding history as its own symbol in a second CSV block within the same Import section, then read it in a formula with Extern. Because multiple data source blocks combine into one data file, the funding series sits alongside the prices and is available on every bar regardless of which instrument is being evaluated.
On perpetual futures, often more than the entry rule. Funding is charged several times a day and in a crowded trade it can exceed the edge being harvested. A backtest that ignores it can show a profitable system that is really collecting a funding subsidy, or paying one.
Wherever the data provider decided, since there is no closing auction. Almost every exchange export uses the UTC midnight boundary. What matters is that every file in a universe uses the same one, because mixing boundaries shifts bars by hours and quietly changes which signals fire.
More than in equities. Exchanges delist pairs frequently and a token that stops trading simply stops appearing in downloads. Building a universe from the pairs listed today and testing it over several years selects for the tokens that survived a period in which most did not.
You can, and it introduces a gap no cost assumption models. Crypto has no consolidated tape, so each venue has its own prices, and the differences are large enough to matter for strategies trading small moves. History should come from the venue you intend to trade.
No. Spot and perpetuals track each other without being the same instrument. Perps carry funding, allow leverage and can dislocate from spot at exactly the moments a strategy is most exposed, so a spot backtest describes something adjacent to what you would actually be trading.