Software for backtesting outside strategies (CSV transaction upload)

I’ve developed some software which generates sets of trades, and I’d like to backtest those trades. My software currently outputs a CSV file with details of each trade:


Is there any backtesting software out there that lets you bring in a set of your own trades, and see how it would have done? All the software I’ve found so far requires to you write your algos directly in the package, and doesn’t simply let you say ‘Buy X, Sell Y’.

Edit based on comments:

  • I don’t include prices or commissions in my CSV because my play here is a long term play (timescale is months or even years). Having the backtesting software use the VWAP (or even just the day’s close) is fine, and with most retail commissions fairly low I could either let the backtesting software add one in or just ignore it. I may not get perfect resolution but (I think) I’d be close enough.
  • I can’t use any of the packages that I’ve found because my algo doesn’t work on the traditional technicals. Instead I’m looking (mostly) at independent stuff, such as 13f data feeds.
  • I can definitely write something in R, or even in my own codebase, but I’m trying to save myself some work on my proof of concept.

Quantitative Finance Asked by dordal on January 20, 2021

5 Answers

5 Answers

You're not really asking how to backtest a strategy. You already have run a backtest to generate simulated trades. What you're asking for is a way to assess the performance of those simulated trades.

You can do this with the R package blotter. You'll need to setup your account and portfolio, then loop over each row in your CSV and call addTxn. For example:

trades <- read.csv("trades.csv")
symbols <- unique(trades$symbol)

# Set up a portfolio object and an account object in blotter
initPortf(name='default', symbols=symbols, initDate=initDate)
initAcct(name='default', portfolios='default', initDate=initDate, initEq=initEq)
verbose = TRUE

for(i in 1:NROW(trades)) {
  addTxn('default', Symbol=trades$symbol[i], TxnDate=trades$date[i],
    TxnPrice={"object-with-price"}, TxnQty=trades$quantity[i], TxnFees=0, verbose=verbose)

# Calculate P&L and resulting equity with blotter
updatePortf(Portfolio='default', Dates=CurrentDate)
updateAcct(name='default', Dates=CurrentDate)
updateEndEq(Account='default', Dates=CurrentDate)

# Look at performance

Correct answer by Joshua Ulrich on January 20, 2021

TuringTrader ( might be worth a look. Or Zorro (

Answered by user42108 on January 20, 2021

With Backtrader in Python should be easy.

For example:

from datetime import datetime
import backtrader as bt

class SmaCross(bt.SignalStrategy):
    def __init__(self):
        sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
        crossover = bt.ind.CrossOver(sma1, sma2)
        self.signal_add(bt.SIGNAL_LONG, crossover)

cerebro = bt.Cerebro()

data0 = bt.feeds.YahooFinanceData(dataname='MSFT', fromdate=datetime(2011, 1, 1),
                                  todate=datetime(2012, 12, 31))

To use your own CSV data, you can define your own custom feed class, e.g.:

import itertools
import backtrader as bt

class MyCSVData(bt.CSVDataBase):

    def start(self):
        # Nothing to do for this data feed type

    def stop(self):
        # Nothing to do for this data feed type

    def _loadline(self, linetokens):
        i = itertools.count(0)

        dttxt = linetokens[next(i)]
        # Format is YYYY-MM-DD
        y = int(dttxt[0:4])
        m = int(dttxt[5:7])
        d = int(dttxt[8:10])

        dt = datetime.datetime(y, m, d)
        dtnum = date2num(dt)

        self.lines.datetime[0] = dtnum[0] = float(linetokens[next(i)])
        self.lines.high[0] = float(linetokens[next(i)])
        self.lines.low[0] = float(linetokens[next(i)])
        self.lines.close[0] = float(linetokens[next(i)])
        self.lines.volume[0] = float(linetokens[next(i)])
        self.lines.openinterest[0] = float(linetokens[next(i)])

        return True

Then load your data and add your strategy:

cerebro = bt.Cerebro()
data = MyCSVData(dataname='file.csv', fromdate=datetime(2019, 1, 1), todate=datetime(2019, 2, 28))


Answered by kenorb on January 20, 2021

With a backtesting library such as and some Python, you could do something like:

import pandas as pd

trades = pd.read_csv('my_trades.csv',
buys = trades[trades.iloc[:,1] == 'Buy']
sells = trades[trades.iloc[:,1] == 'Sell']

from backtesting import Strategy

class MyTrades(Strategy):
    def next(self):
        if in buys:
        if in sells:

Answered by K3---rnc on January 20, 2021

Answering my own question... based on the above comments and a lot of research, it looks like there aren't any packages out there that do this 'out of the box'. So coding your own is the best way to go.

Answered by dordal on January 20, 2021

Add your own answers!

Related Questions

delta neutral option cost

1  Asked on December 28, 2020 by roller


Obtaining current list of companies in the FTSE 100 via an API

3  Asked on December 23, 2020 by thechubbypanda


Converting US Treasury CMT to Discount Yields

1  Asked on December 13, 2020 by mikerand


How to calculate Greeks for leveraged Barrier options?

0  Asked on December 12, 2020 by twhale


Compute the (Net) Present Value

3  Asked on December 5, 2020 by clubkli


Why do not include loan payments in NPV?

3  Asked on December 3, 2020 by henrique-ramos


Ask a Question

Get help from others!

© 2021 All rights reserved.