This introductory lesson is based upon the Quantopian tutorial, as we advance and move into more sophisticated techniques we will move away from their tutorial however I see fit. My goal is to make this simple and informative so that anyone can learn algorithmic trading without too much of a headache!
Here we go:
_________________________________________________________________________________
This is the default "Sample Mean Reversion" tutorial that I am regurgitating from Quantopian.com and in addition I will provide the reader with a deeper understanding of what's going on and why.
Background: Mean Reversion is a statistical method used in finance: Mean Reversion "is the assumption that a stocks price will tend to move to the average price over time"
"When the current market price is less than the average price, the stock is considered attractive for purchase, with the expectation that the price will rise. When the current market price is above the average price, the market price is expected to fall. In other words, deviations from the average price are expected to revert to the average"-https://en.wikipedia.org/wiki/Mean_reversion_(finance)
In other words, a stock that deviates either above or below it's market price will eventually revert back to it's historical mean. We can visualize this using continuous time-series analysis otherwise known as Orstein-Uhlenbeck process. We don't need to go into depth on the Orstein-Uhlenbeck process, but if you would like to know more see Wikipedia, and basic stochastic processes!
Ok, so now we know what a mean reversion is and why we are doing it. It helps us to understand if a stock is a buy or sell value based upon its current market price compared to its historical mean.
Now for the code: (mind you, this is in Python since we are using Quantopian.com).
**Any line that is preceded with a hashtag (#) and is underlined means that it is a 'comment'-comments are used within lines of code by the creator to define a process, or explain why he/she has done something. You do not need to include it in your code!
# Import the libraries we will use here
import numpy as np
**Ok, so import numpy as np is the coding package we are using in our Python module. This allows us to use certain commands as tools and helps us build the algorithm we intend to build!**
# The initialize function is the place to set your tradable universe and define any parameters.
def initialize(context):
# Use the top 1% of stocks defined by average daily trading volume.
set_universe(universe.DollarVolumeUniverse(99, 100))
# Set execution cost assumptions. For live trading with Interactive Brokers
# we will assume a $1.00 minimum per trade fee, with a per share cost of $0.0075.
set_commission(commission.PerShare(cost=0.0075, min_trade_cost=1.00))
# Set market impact assumptions. We limit the simulation to
# trade up to 2.5% of the traded volume for any one minute,
# and our price impact constant is 0.1.
set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.10))
**NOTE: slippage defines how your algorithm will impact the price of the security. As a participant in the market, you will have a small impact on prices depending on how you buy or sell.
# Define the other variables
context.long_leverage = 0.5
context.short_leverage = -0.5
context.lower_percentile = 20
context.upper_percentile = 80
context.returns_lookback = 5
# Rebalance every Monday (or the first trading day if it's a holiday).
# At 11AM ET, which is 1 hour and 30 minutes after market open.
schedule_function(rebalance,
date_rules.week_start(days_offset=0),
time_rules.market_open(hours = 1, minutes = 30))
# The handle_data function is run every bar.
def handle_data(context,data):
# Record and plot the leverage of our portfolio over time.
record(leverage = context.account.leverage)
# We also want to monitor the number of long and short positions
# in our portfolio over time. This loop will check our positition sizes
# and add the count of longs and shorts to our plot.
longs = shorts = 0
for position in context.portfolio.positions.itervalues():
if position.amount > 0:
longs += 1
if position.amount < 0:
shorts += 1
record(long_count=longs, short_count=shorts)
# This rebalancing is called according to our schedule_function settings.
def rebalance(context,data):
# Get the last N days of prices for every stock in our universe.
prices = history(context.returns_lookback, '1d', 'price')
# Calculate the past 5 days' returns for each security.
returns = (prices.iloc[-1] - prices.iloc[0]) / prices.iloc[0]
# Remove stocks with missing prices.
# Remove any stocks we ordered last time that still have open orders.
# Get the cutoff return percentiles for the long and short portfolios.
returns = returns.dropna()
open_orders = get_open_orders()
if open_orders:
eligible_secs = [sec for sec in data if sec not in open_orders]
returns = returns[eligible_secs]
# Lower percentile is the threshhold for the bottom 20%, upper percentile is for the top 20%.
lower, upper = np.percentile(returns, [context.lower_percentile,
context.upper_percentile])
# Select the X% worst performing securities to go long.
long_secs = returns[returns <= lower]
# Select the Y% best performing securities to short.
short_secs = returns[returns >= upper]
# Set the allocations to even weights in each portfolio.
long_weight = context.long_leverage / len(long_secs)
short_weight = context.short_leverage / len(short_secs)
for security in data:
# Buy/rebalance securities in the long leg of our portfolio.
if security in long_secs:
order_target_percent(security, long_weight)
# Sell/rebalance securities in the short leg of our portfolio.
elif security in short_secs:
order_target_percent(security, short_weight)
# Close any positions that fell out of the list of securities to long or short.
else:
order_target(security, 0)
log.info("This week's longs: "+", ".join([long_.symbol for long_ in long_secs.index]))
log.info("This week's shorts: " +", ".join([short_.symbol for short_ in short_secs.index]))
Ok, so run the code over at Quantopian.com or go ahead and run it through your own local Python IDLE and have a look at the results.
If you're running it over at Quantopian.com and want to know the meaning of your results read here:
Next we have alpha; alpha means 'a measure of performance on a risk adjusted basis' and additionally 'The abnormal rate of return on a security or portfolio in excess of what would be predicted by an equilibrium model like the capital asset pricing model (CAPM).' -http://www.investopedia.com/terms/a/alpha.asp
After alpha, we have beta which measures the volatility or risk.
After beta, we have 'Sharpe', which is the 'Sharpe ratio": it measures the risk-adjusted return. The Sharpe ratio is the average return earned in excess of the risk-free rate per unit of volatility or total risk.
Lastly, we have the drawdown: The peak-to-trough decline during a specific record period of an investment, fund or commodity. A drawdown is usually quoted as the percentage between the peak and the trough.
If you have any questions or concerns please send me an e-mail or post a comment!
No comments:
Post a Comment