ml-finance-python

python scripts for finance machine learning

git clone https://9o.is/git/ml-finance-python.git

basic_pairs_trade_optimize_template.py

(3897B)


      1 """
      2 This is a basic pairs trading algorithm that uses the optimize 
      3 WARNING: THIS IS A LEARNING EXAMPLE ONLY. DO NOT TRY TO TRADE SOMETHING THIS SIMPLE.
      4 https://www.quantopian.com/workshops
      5 https://www.quantopian.com/lectures
      6 
      7 For any questions, email max@quantopian.com
      8 """
      9 import numpy as np
     10 import pandas as pd
     11 import quantopian.experimental.optimize as opt
     12 import quantopian.algorithm as algo
     13  
     14 MAX_GROSS_LEVERAGE = 1.0 # Set leverage constraint constant value for optimizer
     15     
     16 def initialize(context):
     17     """
     18     Called once at the start of the algorithm.
     19     """   
     20     # Check status of the pair every day 2 minutes before we rebalance
     21     # The 2 minutes is just because we want to be safe, and 1 minutes
     22     # is cutting it close
     23     schedule_function(check_pair_status, date_rules.every_day(), time_rules.market_close(minutes=60))
     24     
     25     context.stock1 = symbol('ABGB')
     26     context.stock2 = symbol('FSLR')
     27     context.stocks = [context.stock1, context.stock2]
     28     
     29     # Our threshold for trading on the z-score
     30     context.entry_threshold = 0.2
     31     context.exit_threshold = 0.1
     32     
     33     # Create a variable to store our target weights
     34     context.target_weights = pd.Series(index=context.stocks, data=0.0)
     35     
     36     # Moving average lengths
     37     context.long_ma_length = 30
     38     context.short_ma_length = 1
     39     
     40     # Flags to tell us if we're currently in a trade
     41     context.currently_long_the_spread = False
     42     context.currently_short_the_spread = False
     43 
     44 
     45 def check_pair_status(context, data):
     46     
     47     # For notational convenience
     48     s1 = context.stock1
     49     s2 = context.stock2
     50     
     51     # Get pricing history
     52     prices = data.history([s1, s2], "price", context.long_ma_length, '1d')
     53     
     54     # Try debugging me here to see what the price
     55     # data structure looks like
     56     # To debug, click on the line number to the left of the
     57     # next command. Line numbers on blank lines or comments
     58     # won't work.
     59     short_prices = prices.iloc[-context.short_ma_length:]
     60     
     61     # Get the long mavg
     62     long_ma = np.mean(prices[s1] - prices[s2])
     63     # Get the std of the long window
     64     long_std = np.std(prices[s1] - prices[s2])
     65     
     66     
     67     # Get the short mavg
     68     short_ma = np.mean(short_prices[s1] - short_prices[s2])
     69     
     70     # Compute z-score
     71     if long_std > 0:
     72         zscore = (short_ma - long_ma)/long_std
     73     
     74         # Our two entry cases
     75         if zscore > context.entry_threshold and \
     76             not context.currently_short_the_spread:
     77             context.target_weights[s1] = -0.5 # short top
     78             context.target_weights[s2] = 0.5 # long bottom
     79             context.currently_short_the_spread = True
     80             context.currently_long_the_spread = False
     81             
     82         elif zscore < -context.entry_threshold and \
     83             not context.currently_long_the_spread:
     84             context.target_weights[s1] = 0.5 # long top
     85             context.target_weights[s2] = -0.5 # short bottom
     86             context.currently_short_the_spread = False
     87             context.currently_long_the_spread = True
     88             
     89         # Our exit case
     90         elif abs(zscore) < context.exit_threshold:
     91             context.target_weights[s1] = 0 # close out
     92             context.target_weights[s2] = 0 # close out
     93             context.currently_short_the_spread = False
     94             context.currently_long_the_spread = False
     95         record('zscore', zscore)
     96     
     97     # Call the optimizer
     98     allocate(context, data)
     99         
    100         
    101 def allocate(context, data):    
    102     # Set objective to match target weights as closely as possible, given constraints
    103     objective = opt.TargetPortfolioWeights(context.target_weights)
    104     
    105     # Define constraints
    106     constraints = []
    107     constraints.append(opt.MaxGrossLeverage(MAX_GROSS_LEVERAGE))
    108     
    109     algo.order_optimal_portfolio(
    110         objective=objective,
    111         constraints=constraints,
    112         universe=context.stocks
    113     )