from quantopian.interactive.data.sentdex import sentiment
from quantopian.pipeline.filters.morningstar import Q500US, Q1500US, Q3000US
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data import USEquityPricing
from quantopian.pipeline.filters import QTradableStocksUS
from quantopian.pipeline.factors import SimpleMovingAverage
from quantopian.pipeline.data.psychsignal import stocktwits
from quantopian.pipeline.domain import US_EQUITIES
def make_pipeline():
return Pipeline()
from quantopian.research import run_pipeline
result = run_pipeline(make_pipeline(), start_date = '2002-02-01', end_date = '2020-01-01')
len(result)
assets = result.index.levels[1].unique()
len(assets)
result.head()
from quantopian.pipeline.data.sentdex import sentiment
A Sentiment trading strategy involves taking up positions in the market driven by such bulls or bears. The sentiment trading strategy can be momentum based i.e. going with the consensus opinion or market sentiment and if it's a bull we invest high and sell higher or vice versa.
Sentiment is from 6 to -3.
def make_pipeline():
# Create a reference to our trading universe
base_universe = USEquityPricing.specialize(US_EQUITIES)
# Get latest closing price
close_price = USEquityPricing.close.latest
# Calculate 3 day average of bull_minus_bear scores
sentiment_score = SimpleMovingAverage(
inputs=[stocktwits.bull_minus_bear],
window_length=3,
)
# Return Pipeline containing close_price and
# sentiment_score that has our trading universe as screen
return Pipeline(
columns={
'close_price': close_price,
'sentiment_score': sentiment_score,
},
screen=base_universe
)
#Pipeline is where we filter down our companies. Figure out how to keep all 23829 without getting NaN's in sentiment
'''def make_pipeline():
sentiment_factor = sentiment.sentiment_signal.latest
universe = (Q3000US() & sentiment_factor.notnull())
pipe = Pipeline(columns={'sentiment': sentiment_factor,
#Objective is to compare your factor(sentiment) over the entire choosen time span to the market returns of all companies considered.
#We are not really testing/checking our trading startegy using Alphalens, but rather the signal.
#Meaning that even though you might make money from a trading strategy we could be lucky, meaning no alpha, and vice versa.
'longs': (sentiment_factor >=4),
'shorts': (sentiment_factor <=-2)},
screen=universe)
return pipe'''
result = run_pipeline(make_pipeline(), start_date = '2003-01-01', end_date = '2019-12-31')
result.head()
assets = result.index.levels[1].unique()
len(assets)
570 different companies. Figure out how to check all US comanies not just the most liquid companies.
Have to change the universe in order to do that. universe = ((Q1500US()) & sentiment_factor.notnull())
Alpha is a measure of your returns that are irrespective to the market gains.
Want Alpha to be as high as possible(positie at least).
Beta to be as neutral as possible quantopian likes it between 0.3 and -0.3.
Alphalens is a tool for analyzing a given alpha factor's effectiveness at predicting future returns. As a reminder, alpha factors express a predictive relationship between some given set of information and future returns
The objective is to compare your (sentiment)factor over the entire trading period to the market returns of all the assets you might be interested in.
pricing = get_pricing(assets, start_date = '2003-01-01', end_date = '2019-12-31', fields = 'open_price')
result.tail(10)
Going to use Alphalent to test Alpha
import alphalens
factor_data = alphalens.utils.get_clean_factor_and_forward_returns(factor=result['sentiment'],
prices = pricing,
quantiles = 2,
#quantiles: a factor that is going to range from low to high(eg. so cannot use price to book ratio(a company might be worth less than its tangible assets))
#quantiles: have to use 2 quantiles because if we use more it will evenly distribute by sample number(meaning it will relicate numbers rather than use -3,-2,-1 etc to 6, it will eg. -3,-3,-3,-1,-1,1,1,2,4,6,6)
periods = (20,40,60)
)
factor_data.head()
alphalens.tears.create_full_tear_sheet(factor_data, long_short=True )