Coding a simple trading strategy on Python - python

Apologies in advance for the long post (please advice if these long posts are poor form). :(
Attempting to code a simple trading strategy to learn how to calculate expected returns and financial trading methods.
I have here loaded S&P 500 data from Yahoo Finance using yfinance. I then loaded the data, and I wanted the user to be able to input how far back the data goes.
Here already begins my problem. My dataframe is loaded such that the "close_price" list has the dates as an index column (can be seen also in the attached image). Not my biggest concern as I'm able to call all the dates and close_prices for the stock I've selected.
From here, I'm trying to calculate the expected returns based on two strategies:
Buy $x on the first date. Buy $x every month thereafter. Calculate the portfolio value (or returns on each investment/total returns) on a specified date.
Buy $x on the first date. Buy $x again if the price drops by 10%. Sell 0.5*$x if the price increases by 10%. Buy $x if 30 days have surpassed and no buy/sell order has been made.
Picture of my data table
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from pandas_datareader import data as web
# Load stock data
stock_ticker = '^GSPC'
df = yf.download(stock_ticker)
# Allows user to input number of days to trackback prior to today (excluding weekends) for analysis
timescale = int(input("Enter No. of days prior to today (excluding weekends):"))
# List arrays for close price and dates
close_price = df["Adj Close"][-timescale:]
dates = df.index.tolist()[-timescale:]
# Returns
daily_returns = close_price.pct_change(fill_method='pad')
monthly_returns = close_price.resample('M').ffill().pct_change(fill_method='pad')
Things I've tried:
-- Writing a for loop that calculates the multiplies my monthly stock return (monthly return values are of the order 0.01 and stock prices of the order $4000) against my investments per month. So $1000 investment, one month later return is 0.04, so returns are 40, value of portfolio = $1040
-- Write a while loop that is True while the stock prices from the initial value are greater than 0.90% of it. If not True: put $1000 into the stock. If the stock goes up 10% (or if the price from the last buy/sell order is < 1.1x), then sell 50%.
I've tried many ways to logic this in code, but to no avail. Would love your help guys!
Thanks!

There are some modules such as Zipline that can help simulate these trading strategies I think. It might be less time consuming to use that and it incorporates things like slippage and trading fees as well.
However if you want to build your own code from scratch I’d suggest breaking it down into a few smaller steps.
Firstly a section of code that finds trade signals buy/sell, based on your previously stated criteria.
Then another section of code that takes the trading signals and finds trades with entry/exit dates.
When you have a list of trades with entry/exit dates you can create a section of code that turns the list of trades into a portfolio database. The database shows the value of your portfolio over time and how your trades effect that value.

Related

How to include year fixed effect (in a daily panel data)

I am working on a panel dataset that includes daily stock returns of 450 firms for 5 years and daily ESG score(momentum based) for 5 years. I want to regress stock return on daily ESG scores, keeping Firm and year fixed effect. I have used linearmodels.panel function in python and set the index('Stock ticker", "Date") before running the regressions with entity and time effects. In the regression result, the number of entities shows 450, which is perfect but the time period shows 1800. I am wondering how python is capturing the time effects? Is it based on year or some other way? What I want is a year fixed effects, where for a particular year all firm will have same indicator variable. Can someone please help me to do it in the right way?
the image shows the format of the data, where panel is based on daily returns
Sounds like your model is capturing daily fixed effects instead of yearly fixed effects. This is happening because you set Date as an index, so you're telling Python that you want one fixed effect per date.
You have to create a new column that only contains the year. That is, convert the date column to datetime format (see pandas.to_datetime) and then:
# Extract year from Date
df['Year'] = pd.DatetimeIndex(df['Date']).year
# Set indices
df = df.set_index(['Ticker','Year'])
Then run your model.
I recommend using linearmodels.PanelOLS because that module is specifically made for fitting fixed effects models.
For future reference, post your code and a replicable example so we can help you out more easily.

python FIFO stock portfolio calculations

I'm calculating returns for a stock portfolio with hundreds of symbols over a period of many years. I need to evaluate the tax efficiency of this portfolio, which means that I need to account for stock purchases and sales according to FIFO rules of accounting. If I buy a stock and sell it in less than a year, then I pay one tax rate, but if I hold it for over 1 year, I pay a different tax rate. So, for every date, I'd like to calculate the long-term and short-term capital gains for the portfolio from the trades that happen on that date. I'm trying to think of an efficient way to perform these calculations. Ideally, this would be something that would operate on a Pandas DataFrame that contains all of the trades. Perhaps someone knows of a open source portfolio app that already does this? Thanks.

Is there anyway to calculate Market Beta from Yahoo Finance DatasReader on Python?

I'm currently trying to gain market betas from tickers gained through yahoo finance datasreader. I was wondering if there is a way to calculate each stocks market beta, and put it in a dataframe?
This is what I have for my code so far:
import pandas_datareader.data as pdr
Tickers=['SBUX','TLRY']
SD='2005-01-31'
ED='2018-12-31'
TickerW=pdr.datareader(Tickers,'yahoo',SD,ED)
TickerW.head()
Okay, to make sure we're on the same page, we use the formula and definition of market beta from here: https://www.investopedia.com/terms/b/beta.asp
Beta = Covariance(Stock Returns, Market Returns) / Variance(Market Returns)
So first of all, we need the tickers for the market as well as the tickers for the stock. Which ticker you use here depends a lot on what market you want to compare against: Total stock market? Just the S&P 500? Maybe some other international equity index? There's no 100% right answer here, but a good way to pick is think about who the "movers" of your stock are, and what other stocks they hold. (Check out Damodaran's course on valuation, free on the interwebs if you google it).
So now your question becomes: How do I compute the covariance and variance of stock returns?
First, the pandas tickers have a bunch of information. The one we want is the "Adjusted Close". That's the daily closing price of the stock, retroactively adjusted for any "special" events like stock splits, reverse splits, and dividends. Because let's say a stock trades for $1000 a pop one day, but then undergoes a 1 for 2 stock split, so now instead of 1 share for $1000, you have 2 shares for $500 each. In a "raw" price chart, it would appear as if your stock just lost 50% value in a single day when in reality nothing happened. The Adjusted Close time series takes care of that to make sure that only "real" changes to the stock's value are reflected.
You can get that by calling prices = TickerW['Adj. Close'] or whatever key yahoo finance uses these days. By just looking at the TickerW dataframe you should be able to figure that out on your own :)
Next, we'd be changing prices into returns. That's just prices.shift(1) / prices (or maybe the other way round :D consult the documentation and try it out yourself). (Nerd note: Instead of these returns, it is mathematically more sound to use the logarithmic returns, because they have certain reasonable properties. If you want, throw a "log" around the returns.
Finally, we now have a series of returns (or log returns). One series for the stock returns, one for the market returns (e.g. from SPY, for the S&P 500). Now we just need to use them in the formula for beta.
Well, the way to go here is to do what I just did: Hit up google for "pandas covariance between two series" and that gets us to https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.cov.html
So basically, cov = stock_returns.cov(market_returns) and var = market_returns.var and then beta = cov / var.
I'd say that should be enough info to send you on your way. Good luck.

Converting a single row into two

I have this daily stats churned out from a system which outputs total sales and units sold per region group. For my analysis, I want to breakdown the entries into regions instead of region group. I'm trying to look for a way to split each row into per region with the respective measures.
I have historical percentages on the market share per region which I'll use to come up with the estimated sales and units sold.
I can do this manually in excel but given how i'll be doing this on a weekly basis, I'm looking for a way to automate it via python.
My data: https://imgur.com/a/pBr3y4D
Goal: https://imgur.com/a/Uc56PVR
Well, first of all, when you're doing DS researches try to find the most appropriate way in your personal case. There's nothing bad in using all Excel functionality to solve your issue, scripting, etc.
However, if you really-really want to use pandas, then what I would do in your case - just .append() and then split on regions and grouping by sales or made up a function with for..loop.

JPYLibor fixing during Japanese holiday: negative time error

I am using QuantLib 1.7 with the Python interface.
I have constructed the JPY Fixed-Float swap curve following the standard convention. For the swap schedules I have a JointCalendar with Japan and UnitedKingdom. My JPYLibor index has the UK calendar only.
When I set the market date to 2009-May-1, I do a bootstrap using PiecewiseFlatForward with settlement date 2009-May-8 because in the Japan calendar there was a long holiday from 2009-May-4 (monday) to 2009-May-6.
Now, with this bootstraped curve, I try to value a swap that has a floating payment on 2009-May-7. When I try to value it (or compute the amount() function of the next floatingLeg cashflow which has a reset date on 2009-May-5) I get the error message "2nd leg: negative time (-0.00277778) given".
I guess that this is related to the fact that 2009-May-5, which is the London fixing date for value date 2009-May-7, falls on a Japanese holiday?
My swap payments schedules and reset schedule are matching Bloomberg so I am confident in theory is the correct convention. I have read some old posts regarding apparently a similar issue for a US swap, but as far as I understood this was a bug which was corrected around the time of QuantLib 0.9.
Could my problem be related to the same bug or I am not using QuantLib correctly?
The problem is that the value date for the payment, May 7th, is between today's date and the reference date of the curve. The fixing needs to be forecast, since it's in the future (the fixing date is on May 5th); but because the curve effectively starts on May 8th, it can't return the May 7th discount which is required to forecast the fixing.
The reason why this doesn't usually happen is that, when the value date is between today and the reference date, the fixing date is usually before today's date and thus the fixing can be loaded from past ones.
In this particular case, the way to make it work would be to create a curve with no settlement days so that its reference date is the same as today's date. If you then wanted the price as-of May 8th, you'd have to manually adjust the swap NPV for the discount between May 1st and 8th.

Categories