Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Backtest a portfolio of stocks (cross-sectionally rather than one stock at a time) #895

vchopra9 started this conversation in General
Discussion options

Is it possible to run and evaluate cross-sectional backtests using backtesting.py (or another resource)? For example, I want to calculate a simple moving average crossover strategy signal (20 days vs 200 days), apply it to every stocks in the Dow Jones index, and restrict my Buy universe to only those stocks that meet the buy condition (sma(20)>=sma(200)). From within this Universe, I want the rank every stock using a measure of momentum (3 month price change) and pick the top 10 stocks to create a portfolio. Each stock is equal-weighted.

Then I want to evaluate the performance of this portfolio over time and compare it with the performance of the Dow Jones index itself. What is the best Python resource for doing this?

You must be logged in to vote

Replies: 4 comments

Comment options

I have been wondering the same thing myself.

You must be logged in to vote
0 replies
Comment options

Did this ever get addressed? It seems like a great tool, but the ability to simulate a strategy on a portfolio of stocks is essential for it to be truly useful. For example, how would we build a portfolio of relative value strategies that are buying and shorting multiple single-name stocks and hedging against that via sector ETFs and SPY? How do we address position sizing too?

You must be logged in to vote
0 replies
Comment options

I do think this is essential. I'm struggling with a similar problem right now.

As a newbie, I would like to implement a strategy like this:

Sort the ROC based on several indices, then hold the ETF corresponding to the one with ROC value greater than 0 and the highest; if ROC is less than 0, close the position; and if there is no eligible one, hold nothing.

I can't imagine how to implement such a strategy if backtesitng.py doesn't support portfolios.

You must be logged in to vote
0 replies
Comment options

Is it possible to run and evaluate cross-sectional backtests using backtesting.py (or another resource)? For example, I want to calculate a simple moving average crossover strategy signal (20 days vs 200 days), apply it to every stocks in the Dow Jones index, and restrict my Buy universe to only those stocks that meet the buy condition (sma(20)>=sma(200)). From within this Universe, I want the rank every stock using a measure of momentum (3 month price change) and pick the top 10 stocks to create a portfolio. Each stock is equal-weighted.

Then I want to evaluate the performance of this portfolio over time and compare it with the performance of the Dow Jones index itself. What is the best Python resource for doing this?

I'm no coding expert, but you can do this. One way to do it:

  1. Create a list of the ticker symbols symbols =[GOOG, AAPL... etc]
  2. Create an open list output_data [] for your OHLCV data and use a for loop like for symbol in symbols: and possibly a while loop (if you need more than one download per symbol) to get the candlestick info from your http of choice and you could use something like output.append to collate each symbol's data into the same list
  3. You could then create a dictionary of Pandas DataFrames for each symbol from your output_data list
  4. Add your SMAs to each of the DataFrames in the dictionary, something like...
def get_sma (df, symbols):
 sma_dict = {}
 for symbol in symbols:
 df[symbol]['SMA_20'] = df[symbol]['Close'].rolling(window=20).mean()
 df[symbol]['SMA_200'] = df[symbol]['Close'].rolling(window=200).mean()
 sma_dict[symbol] = df[symbol]
 return sma_dict 

Then you can go through each of the symbols with your strategy and create a dictionary of strategy results for each symbol bt_dict = {}:

def get_backtests (df, symbols):
 bt_dict = {}
 for symbol in symbols: 
 class SMA_Strategy (Strategy): 
 .....
 def init(self):
 .....
 def next(self): 
 ..... 
 strategy = Backtest(df[symbol], SMA_Strategy, cash=1000, commission=0.0012, 
 exclusive_orders=True, trade_on_close = True)
 bt_dict[symbol] = strategy
 
 return bt_dict

You can then run for each to get the % return (could also optimize them):

def get_optimized_perc_return (symbols):
#run the backtest for each optimized symbol and extract the % return into a dictionary
 perc_return_dict = {}
 for symbol in symbols:
 data = bt_dict[symbol].run()
 perc_return_dict[symbol] = data['Return [%]'] 
 return perc_return_dict

Will give you an output of % returns like so (these are Crypto symbols):

{'ADA': 10511.574367480083,
 'ALGO': 323.7279923600059,
 'ATOM': 2611.542394400133,
 'AVAX': 108.04964600000784,
 'BNB': 33394.865310000336,
 'BTC': 895.9949103094484,
 'DOGE': 126.24115159000281,
 'DOT': 110.60550839999567,
 'ENJ': 686.571106400039,
 'EOS': 30.951823200004952,
 'ETH': 2125.768743695629,
 'FTM': -57.9659569799996,
 'GALA': 2.8077984820149737,
 'LDO': 1286.174079800069,
 'LINK': 630.2519779999596,
 'LTC': 638.0804719999867,
 'MANA': 1232.655085759999,
 'MATIC': 26030.410032660093,
 'NEAR': 5985.613275400312,
 'OP': 884.0031728600737,
 'SAND': 1044.6085923400283,
 'SHIB1000': 20590.572847876225,
 'SOL': 11998.26908360012,
 'UNI': 29.26338139999285,
 'XLM': 607.0129853400073,
 'XRP': 127.0297076600018}

In short, you need to know some coding, and I am sure there are way more "Pythonic" ways to do it versus the above, but hopefully helps.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /