<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Stock Trading Strategy Backtesting
Author
Step1:  Download data
This project will use the historical daily closing quotes data for S&P 500 index from January 3,2000 to December 9,2016, which can be found on Quandl at this link. S&P 500 index is generally considered to be a good proxy for the whole stock market in the United States. Quandl provides an API which can be used to download the data.
API
Step2:  Clean data
The time series data for the S&P 500 index is now in the dataframe sp500 which automatically has index as datetime objects. I will keep data in the column Close and drop any other data that this project is not going to use.
Step3:  Plot the closing quotes over time to get a fisrt impression about the historical market trend by using plotly package. In the following graph, not only can you observe the trend from the start date to the end date but also use the range selectors in the upper left corner and the range slider at the bottom to see the trend in a specific period of time.
Step4:  Generate trend lines
The trading strategy I am going to test is based on both a two-month(i.e., 42 trading days) trend line and a one-year(i.e., 252 trading days) trend line. Trend line is formed of the moving average of the index level for the corresponding time period. To generate the two kinds of trend lines, first, the data of moving average of the S&P 500 index in respective period should be calculated. Two new columns are added to the dataframe sp500, the column 42d contains values for the 42-day trend and the column 252d contains the 252-day trend data.
Step5:  Notice that these two new columns have fewer entries because they start having data only when 42 and 252 observation points, respectively, are available for the first time to calculate the moving average. Then, plot these two trend lines in a single figure with the historical level of S&P 500 index. You can still use the range selectors and the range slider to observe a certain period. Also, a trend line will disappear if you click on the corresponding legend in the upper right corner of the graph. This function makes it easier to get some insights from those upward and downward trends.
Step6:  Generate trading signals
The stock investment strategy which is going to be tested is based on trading signals generated by the 42-day and 252-day trends created above. The following rule generates trading signals
Step7:  After the differences between the 42-day trend and the 252-day trend being calculated, the trading signals are generated according to the rule. The signal "1" means to have long positions in the index and get the market returns. The signal "0" means not to buy or sell the index and make no returns. The signal "-1" means to go short on the index and get the negative market returns.
Step8:  The result shows that from January 3,2000 to December 9,2016, there were 1935 trading days when the 42-day trend was more than 50 points above the 252-day trend. On 950 trading days, the 42-day trend lies more than 50 points below the 252-day trend. The change of signals over time can be seen in the following graph.
Step9:  Does the trading strategy perform well?
Test the performance of the investment strategy based on trading signals generated above by comparing the cumulative,continuous market returns with the cumulative, continuous returns made by the strategy. Daily log returns are calculated here.
Step10:  Plot the market returns and the returns of the strategy over time to see the performance of the trading strategy constructed on trend lines. As before, You can use the range selectors and the range slider to check whether the strategy works well in a certain period of time.
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from plotly.offline import init_notebook_mode,iplot
import plotly.graph_objs as go 
%matplotlib inline
init_notebook_mode(connected=True)
Explanation: Stock Trading Strategy Backtesting
Author: Long Shangshang (Cheryl)
Date: December 15,2016
Summary: Test a trading system based on market trend signals. Does technical analysis really work?
Description: Technical analysis is a security analysis methodology for forecasting the direction of prices through the study of past market data, primarily price and volume. Many financial professionals and interested amateurs apply technical analysis to stock investments. They predict future price trends and develop trading strategies using historical market data.In this project, I am going to test the performance of an investment strategy based on trading signals generated by two-month and one-year trend lines. 
Outline:
* Download data: get the daily closing quotes data for S&P 500 index
* Clean data: observe the historical market trend 
* Generate trend lines: develop the two-month and one-year trend lines 
* Generate trading signals: form the trading signals based on a rule
* Backtest the strategy: see if the strategy outperforms the market
This Jupyter notebook was created with a lot of help from Spencer Lyon and Chase Coleman for the NYU Stern course Data Bootcamp.
End of explanation
import quandl
sp500=quandl.get("YAHOO/INDEX_GSPC",start_date="2000-01-03",end_date="2016-12-09")
sp500.info()
sp500.head()
type(sp500.index)
Explanation: Download data
This project will use the historical daily closing quotes data for S&P 500 index from January 3,2000 to December 9,2016, which can be found on Quandl at this link. S&P 500 index is generally considered to be a good proxy for the whole stock market in the United States. Quandl provides an API which can be used to download the data.
API:  YAHOO/INDEX_GSPC
Parameters:
start_date: Specified in format  year-month-day
end_date: Specified in format  year-month-day
Note:  The Quandl Python package should be installed already. If not, enter 
pip install quandl from the command line (command prompt on windows, terminal on mac) to install it.
End of explanation
sp500=sp500.drop(['Open','High','Low','Volume','Adjusted Close'],axis=1)
sp500.head()
Explanation: Clean data
The time series data for the S&P 500 index is now in the dataframe sp500 which automatically has index as datetime objects. I will keep data in the column Close and drop any other data that this project is not going to use.
End of explanation
trace = go.Scatter(x=sp500.index,
                   y=sp500['Close'])
data=[trace]
layout = dict(
    width=1000,
    height=600,
    title='Historical levels of the S&P 500 index',
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                    label='1y',
                    step='year',
                    stepmode='backward'),
                dict(count=5,
                    label='5y',
                    step='year',
                    stepmode='backward'),
                dict(count=10,
                    label='10y',
                    step='year',
                    stepmode='backward'),
                dict(step='all')
            ])
        ),
        rangeslider=dict(),
        type='date'
    )
)
fig = dict(data=data, layout=layout)
iplot(fig)
Explanation: Plot the closing quotes over time to get a fisrt impression about the historical market trend by using plotly package. In the following graph, not only can you observe the trend from the start date to the end date but also use the range selectors in the upper left corner and the range slider at the bottom to see the trend in a specific period of time.
End of explanation
sp500['42d']=sp500['Close'].rolling(window=42).mean()
sp500['252d']=sp500['Close'].rolling(window=252).mean()
sp500.tail()
Explanation: Generate trend lines
The trading strategy I am going to test is based on both a two-month(i.e., 42 trading days) trend line and a one-year(i.e., 252 trading days) trend line. Trend line is formed of the moving average of the index level for the corresponding time period. To generate the two kinds of trend lines, first, the data of moving average of the S&P 500 index in respective period should be calculated. Two new columns are added to the dataframe sp500, the column 42d contains values for the 42-day trend and the column 252d contains the 252-day trend data.
End of explanation
trace1 = go.Scatter(x=sp500.index,
                    y=sp500['Close'],
                    name='close')
trace2 = go.Scatter(x=sp500.index,
                    y=sp500['42d'],
                    name='42d')
trace3 = go.Scatter(x=sp500.index,
                    y=sp500['252d'],
                    name='252d')
data=[trace1,trace2,trace3]
layout = dict(
    width=1000,
    height=600,
    title='The S&P 500 index with 42-day and 252-day trend lines ',
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                    label='1y',
                    step='year',
                    stepmode='backward'),
                dict(count=5,
                    label='5y',
                    step='year',
                    stepmode='backward'),
                dict(count=10,
                    label='10y',
                    step='year',
                    stepmode='backward'),
                dict(step='all')
            ])
        ),
        rangeslider=dict(),
        type='date'
    )
)
fig = dict(data=data, layout=layout)
iplot(fig)
Explanation: Notice that these two new columns have fewer entries because they start having data only when 42 and 252 observation points, respectively, are available for the first time to calculate the moving average. Then, plot these two trend lines in a single figure with the historical level of S&P 500 index. You can still use the range selectors and the range slider to observe a certain period. Also, a trend line will disappear if you click on the corresponding legend in the upper right corner of the graph. This function makes it easier to get some insights from those upward and downward trends.
End of explanation
sp500['42-252']=sp500['42d']-sp500['252d']
sp500['42-252'].tail()
Explanation: Generate trading signals
The stock investment strategy which is going to be tested is based on trading signals generated by the 42-day and 252-day trends created above. The following rule generates trading signals:
* Buy: when the 42-day trend is for the first time 50 points above the 252-day trend
* Wait: when the 42-day trend is within a range of +/- 50 points around the 252-day trend
* Sell: when the 42-day trend is for the first time 50 points below the 252-day trend
In this project, it is assumed that an invester can directly buy or sell the S&P 500 index. The transaction costs will be caused in the real market is not considered here.
End of explanation
sp500['Signal']=np.where(sp500['42-252']>50,1,0)
sp500['Signal']=np.where(sp500['42-252']<-50,-1,sp500['Signal'])
sp500['Signal'].value_counts()
Explanation: After the differences between the 42-day trend and the 252-day trend being calculated, the trading signals are generated according to the rule. The signal "1" means to have long positions in the index and get the market returns. The signal "0" means not to buy or sell the index and make no returns. The signal "-1" means to go short on the index and get the negative market returns.
End of explanation
figure,ax=plt.subplots()
sp500['Signal'].plot(ax=ax,lw=1.3,fontsize=10,
                     ylim=[-1.1,1.1],
                     title='Trading signals over time',
                     grid=True)
Explanation: The result shows that from January 3,2000 to December 9,2016, there were 1935 trading days when the 42-day trend was more than 50 points above the 252-day trend. On 950 trading days, the 42-day trend lies more than 50 points below the 252-day trend. The change of signals over time can be seen in the following graph.
End of explanation
sp500['Market returns']=np.log(sp500['Close']/sp500['Close'].shift(1))
sp500['Strategy returns']=sp500['Signal'].shift(1)*sp500['Market returns']
sp500[['Market returns','Strategy returns']].cumsum().apply(np.exp).tail()
Explanation: Does the trading strategy perform well?
Test the performance of the investment strategy based on trading signals generated above by comparing the cumulative,continuous market returns with the cumulative, continuous returns made by the strategy. Daily log returns are calculated here.
End of explanation
return1 = go.Scatter(x=sp500.index,
                    y=sp500['Market returns'].cumsum().apply(np.exp),
                    name='Market')
return2 = go.Scatter(x=sp500.index,
                    y=sp500['Strategy returns'].cumsum().apply(np.exp),
                    name='Strategy')
data=[return1,return2]
layout = dict(
    width=1000,
    height=600,
    title='The market returns vs the strategy returns ',
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                    label='1y',
                    step='year',
                    stepmode='backward'),
                dict(count=5,
                    label='5y',
                    step='year',
                    stepmode='backward'),
                dict(count=10,
                    label='10y',
                    step='year',
                    stepmode='backward'),
                dict(step='all')
            ])
        ),
        rangeslider=dict(),
        type='date'
    )
)
fig = dict(data=data, layout=layout)
iplot(fig)
Explanation: Plot the market returns and the returns of the strategy over time to see the performance of the trading strategy constructed on trend lines. As before, You can use the range selectors and the range slider to check whether the strategy works well in a certain period of time.
End of explanation
<END_TASK>