Factor Investing Library
Project description
Factor Investing LIBrary is a lightweight algorithmic trading Python library built for easy testing of predictive factors and portfolio rebalance via Oanda. Inspired by and compatible with Quantopian Open Source.
NOTE: This library is currently in alpha stage. Until it becomes stable I strongly recommend using practice account for testing and trading. You can also expect major changes without warnings, mostly responses to Issues.
Installation
Install with pip:
$ pip install filib
Usage
Proposed workflow contains three steps. Here’s an example:
1. Assemble
Begin with imports, create hypotheses and write functions with predictive factors:
from filib.oanda import Oanda # Currently only Oanda FOREX is available
from filib.helpers import * # Optional, useful for factor generation
class MyFactors(Oanda):
def momentum(self): # THEORY: Persistence in asset performance
factor = self.returns # Write down your factor formula
return factor # By default split factor data to 3 quantiles
@swap_sign # Short high and long low factor values
def relative_strenght_index(self): # THEORY: Oversold / overbought indicator
factor = rsi(self.close, 14)
split = [0, 30, 70, 100] # List of thresholds or int to split equally
return factor, split # Follow this order: factor, split
def big_mac_index(self): # THEORY: Simplified Purchasing Power Parity
import quandl # Financial, Economic and Alternative Data
iso_codes = get_iso_codes(self.price_data)
codes = [f"ECONOMIST/BIGMAC_{COUNTRY}.5" for COUNTRY in iso_codes]
factor = quandl.get(codes).dropna(how="all", axis=1)
factor.columns = [iso_codes[c.split("_")[1].split()[0]] for c in factor]
factor.index = factor.index.tz_localize("UTC") # Convert time zone to UTC
return factor
2. Research
Initialize parameters (during the first run you will be asked to provide credentials):
model = MyFactors(
instruments=["EUR_USD", "GBP_USD", "USD_JPY", "AUD_USD", "NZD_USD", "USD_CAD",
"USD_CHF", "USD_NOK", "USD_SEK"], # Define universe
symbol="USD", # Optional, specify symbol to arrange price data
granularity="D", # Time period between each candle and between each rebalance
count=500, # Number of historical OHLCV candles to return for analysis
periods=(1, 2, 3), # Optional, specify periods for factor decay analysis
split=3, # Number of quantiles to split combined factor data
long_short=True, # Trade only top and bottom factor quantile
combination="sum_of_weights", # Formula for combining factors together
leverage=3, # Multiplier for the portfolio positions
)
Check the performance of factors combined together:
>>> model.performance()
Collecting price data: |██████████████████████████████| 9/9 [100%] in 4.0 s
Preparing factor data: |██████████████████████████████| 3/3 [100%] in 12.0 s
MyFactors - INFO - Factor `MyFactors_combined` Analytics:
Min Max Mean Size Returns (bps)
factor factor factor factor 1D 2D 3D
factor_quantile
1.0 -1.003 0.000 -0.237 1499 -1.337 -2.068 -2.320
2.0 -0.243 0.210 0.005 1461 -2.582 -3.299 -5.138
3.0 -0.027 0.973 0.238 1459 0.892 -0.835 -2.266
1D 2D 3D
- Information Coefficient: 0.037 0.001 0.0
- Factor Rank Autocorrelation: 0.05
- Annualized Sharpe Ratio: 0.76
- Annualized Alpha (Beta): 0.080 (0.042)
- Win Rate: 52.55%
- Risk / Reward: 1.02
- Profit Factor: 1.15
- Start Date: 2018-07-11
- End Date: 2020-05-27
- Duration: 686 days 00:00:00 (1.9 years)
- Rebalance every: 1D
- Compound Annual Growth Rate: 7.78%
- Annualized Volatility: 10.44%
- Maximum Drawdown: -11.49%
- Maximum Drawdown Duration: 434 days 00:00:00
...
Alternatively set selection rules with a query string to evaluate. Available metrics:
ic: Information Coefficient based on Spearman Rank Correlation
autocorr: Factor Rank Autocorrelation
sharpe: Annualized Sharpe Ratio
beta: Annualized Beta as exposure to trading universe
alpha: Annualized Alpha as excess returns over trading universe
win: Win Rate
rr: Risk / Reward Ratio
profit: Profit Factor = (sum of earnings) / (sum of losses)
cagr: Compound Annual Growth Rate
Then analyze the performance of individual factors and select those that meet the rules:
>>> model.select(
... rules="abs(ic) > .01 or profit > 1", # Example query expression
... swap_to="cagr", # Align the signs of selected factors to specified metric
... inplace=True, # Modify model to contain only selected factors
... )
Preparing performance: |██████████████████████████████| 3/3 [100%] in 6.2 s
MyFactors - INFO - Factors with signs that meet the rules `abs(ic) > .01 or profit > 1`:
big_mac_index -1.0
momentum 1.0
relative_strenght_index 1.0
3. Trade
Check portfolio positions based on selected factors and generated submitted orders:
PLEASE USE AT YOUR OWN RISK - THIS CAN TRADE REAL MONEY - NO WARRANTY IS GIVEN
>>> model.rebalance(
... accountID="", # Your Oanda Account Identifier
... live=True, # Actually place orders
... )
MyFactors - INFO - Portfolio from `2020-05-28 00:00:00+00:00`:
NOK -19.5%
SEK -15.3%
CHF -15.2%
AUD 0.0%
EUR 0.0%
GBP 0.0%
NZD 9.0%
CAD 15.3%
JPY 25.8%
- Account NAV: 8423.77 EUR
- Position Value: 25382.12
- Submitted Orders:
USD_JPY -7240
NZD_USD 4050
USD_CAD -4280
USD_CHF 4260
USD_NOK 5490
USD_SEK 4280
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.