Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@yanofsky
Created December 16, 2013 23:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yanofsky/7996646 to your computer and use it in GitHub Desktop.
Save yanofsky/7996646 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# encoding: utf-8
import sys
import os
import csv
import datetime
#define market holidays
marketHolidays = ["2013-01-21","2013-02-18","2013-03-29","2013-05-27","2013-07-04","2013-09-02","2013-11-28","2013-12-25"]
def main():
data = []
#this is a spreadsheet with all of the data
#the first column is dates, every subsiquent column is the closing price of a stock (the ticker is the header)
#i.e. every row is a day of data
with open("perfectsp500raw.csv","rb") as f:
#open the file turn every row into a dict with the tickers as the keys
reader = csv.DictReader(f)
#cache the tickers to make things easier
headers = reader.fieldnames
rawdata = []
#put the data into a list to make it easier to work with
for row in reader:
rawdata.append(row)
for i in range(1,len(rawdata)):
#loop through all of the data
thenrow = rawdata[i]
nowrow = rawdata[i-1]
#convert the date column into a native date object
nowdate = datetime.datetime.strptime(nowrow["date"],"%Y-%m-%d")
#skip the day if it's a weekday or a market holiday
if nowdate.weekday() > 4 or nowrow["date"] in marketHolidays:
continue
#initialize a dummy row of data to fill in later
data_row = {"date":nowrow["date"],"max": DayInfo("NADA",float("-inf"),float("-inf"))}
#loop through every ticker (the first one is the date)
for j in range(1,len(headers)):
ticker = headers[j]
#some days don't have data (they weren't listed then or didn't trade that day or otherwise)
#set the price on that day to 0 (0's are ignored)
try:
now = float(nowrow[ticker])
except:
now = 0
try:
then = float(thenrow[ticker])
except:
then = 0
#create a DayInfo object using the ticker and the one day close to close change
data_row[ticker] = DayInfo(ticker,now,pctChange(now,then))
#if the the current company has the largest pct change set it as the max for the day
data_row["max"] = max(data_row["max"],data_row[ticker])
#add the row to the cleaned data list
data.append(data_row)
#set a amount of money to start with
val = 1000
#set a trading fee
fee = 0
data = reversed(data)
for row in data:
#convert the pct change into a factor to multiply the running total by
factor = row["max"].pctChng + 1
#calculate the effect of the trade on the running total
val = val*factor - (fee * 2) #this isn't exactly right, on the first day there is only the buy fee and on the last day there is only the sell fee
#print out the date, a the running value as formatted number, the change, and the Day info object for the max (ticker + price)
print "%s\t%s\t%s\t%s" % (row["date"], "{:,}".format(val/1000), float(round(row["max"].pctChng*10000))/100, row["max"])
pass
def pctChange(now,then):
if now == 0 or then == 0:
#this effectively ignores 0 prices
return float("-inf")
return (now-then)/then
class DayInfo():
"""dayInfo is a custom class i created so I could use the max function and not have to keep track separately of the ticker"""
def __init__(self, ticker, val,pctChng):
self.ticker = ticker
self.val = val
self.pctChng = pctChng
def __cmp__(self, other):
#on comparison, use pctChng to compare
if self.pctChng == other.pctChng:
return 0
elif self.pctChng > other.pctChng:
return 1
return -1
def __repr__(self):
#on print use ticker {tab} price
return "%s\t%s" % (self.ticker,self.val)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment