Wednesday, 3 June 2015

Moving Average Crossover in Python

Developing a successful algorithmic trade strategy is a challenging task, and not just because it is difficult to predict price movements based on past behavior (this is close to what we all have been taught and probably learned in our day-to-day lives). The underlying idea behind algo trading is to exploit market patterns. But market patterns do change, so fast reaction is crucial.
I was trying recently to work on some algo trade codes on Python (Python 2.7) and I ended up for a simple moving average crossover code (15-day moving average and 50-day moving average). The example is for Microsoft shares (ticker: MSFT). Moving average crossover signal is: (i) buy when 15-day moving average crossed above the 50-day moving average and (ii) sell when the 15-day moving average crossed below the 50-day moving average.

Inspired by Aaron Ash’s post “Fun With Python” (http://aaronash.com.au/posts/fun_with_python/) here is what I get:

import pandas as pd
from pandas import *
import StringIO
import urllib
import datetime
import matplotlib.pyplot as plt

%matplotlib inline

def get_data(ticker):
    base_url = 'http://ichart.finance.yahoo.com/table.csv?'
    search_query = 's={}'.format(ticker)
    search_url = '{}{}'.format(base_url, search_query)
    read_url=urllib.urlopen(search_url).read()
    return read_url

# for Python 3.4: read_url=urllib.request.urlopen(search_url).read(); for Python 2.7: read_url=urllib.urlopen(search_url).read()

if __name__ == '__main__':
    ticker = 'MSFT' #select ticker

data=get_data(ticker)

lines = data.split('\n')
lines.reverse()
lines[0] = lines[-1]
cleaned_data = "\n".join(lines[0:-1])
data = read_csv(StringIO.StringIO(cleaned_data))
data.tail() # to see how the data looks like

# calculate the 15-day and 50-day simple moving average (MA)
data['MA_15'] = rolling_mean(data.Close, 15)
data['MA_50'] = rolling_mean(data.Close, 50)
previous_15 = data['MA_15'].shift(1)
previous_50 = data['MA_50'].shift(1)

crossing = (((data['MA_15'] <= data['MA_50']) & (previous_15 >= previous_50))
| ((data['MA_15'] >= data['MA_50']) & (previous_15 <= previous_50)))
crossing_dates = data.loc[crossing, 'Date']
print(crossing_dates)
#see where are the crossing points, triggering action

final=DataFrame(data, columns=['Date', 'Close', 'MA_15', 'MA_50'])
final['Date'] = pd.to_datetime(final['Date'])
for_chart=final[final['Date'] >= datetime.date(2013,1,1)]  #to see the results since Jan 1, 2013

# plot the results since Jan 1, 2013
for_chart.plot('Date', 'Close')
for_chart.plot('Date', 'MA_15')
for_chart.plot('Date', 'MA_50')
plt.legend(['Close', 'MA_15', 'MA_50'], loc='upper left')

To see the crossover dates triggers (buy or sell):

crossing_dates=pd.DataFrame(crossing_dates, columns=['Date'])
final=pd.DataFrame(data, columns=['Date', 'Close', 'MA_15', 'MA_50'])
result=crossing_dates.merge(final, on='Date')
result

result['Strategy'] = 0
condition = result['MA_15'] > result['MA_50']
result.loc[condition, 'Strategy'] = 'Buy'
result.loc[~condition, 'Strategy'] = 'Sell'
result


1 comment:

  1. hello Elena,
    How are you doing?

    Great work Elena! Can you please post this phyton program for a 5 minutes time chart?

    ReplyDelete