Skip to main content

Conintegration method

Project description

This programme is used for statistical arbitrage with co integation method

Dependencies

  • python 3.5
  • pandas 0.22.0
  • spyder 3.2.8
  • joblib 0.12.3
  • RNWS 0.1.2
  • mini_exchange 0.0.7

Sample

Back Test

Calculate p_value of stationarity among all pairs along all history

import pandas as pd
from CointArbitrage.pairing_period import find_pair,filter_tickers

price=pd.read('price.csv') # index:yyyymmdd(int),columns:tickers,values:adjusted price

past_date=60 # use last 60 days to calculate p_value
P=[]
for i in range(past_date,price.shape[0]):
    # filter unavailable tickers, this step is optional
    df=filter_tickers(price.iloc[(i-past_date):i])
    # calculate p_value
    des=find_pair(df,mul=True,n_jobs=-1)
    dt=filter_tickers.index[i]
    P.append(pd.Series(des.p_value.values,index=des['ticker1'].str.cat(des['ticker2'],'|').values,name=dt))
pairs=pd.concat(P,axis=1).T

Make signal dataframe

from CointArbitrage.trading_period import zscore_log_w,zscore_w,sig,sig_cut_tail
window=20 # use 20 days to calculate zscore ( = normalize(stockPrice1/stockPrice2))
ratio,zs=zscore_w(price_df=price,pair_lst=pairs.columns,window=window)
# or use log zscore = normalize(log(stockPrice1/stockPrice2))
ratio,zs=zscore_log_w(price_df=price,pair_lst=pairs.columns,window=window)
# or use exponential moving to calculate zscore with function zscore_df and zscore_log_df

# generate signal
# k0: close position, int, float or pd.Series if need to specify different values for each pairs
# k1: open position
# k2: close out position
k0,k1,k2=1,2,4
sig_df=sig(zscore=zs,k0=k0,k1=k1,k2=k2)
# sig_df contains value Nan,-3,-2,-1,0,1,2,3
# 3(-3) means close position and open another position in different direction
# 2(-2) means close position
# 1(-1) means open position
# keep signal when stationary (i.e. p_val<0.1), others would be kept in Nan
# and add a new signal 4(-4), which means reaching the end of stationarity period
sig_result=sig_cut_tail(sig_df,pairs<0.1,n_jobs=-1,new_signal=4)

Simulate trade

from CointArbitrage.trading_period import Trade
start=20140101
end=20180101
TT=Trade(price,start=start,end=end)
user_name='user01'
TT.add_user(user_name,sig_result,start_amount=1000)
# add signal 4 as close signal
# and leave close status as -1 (default close status is 0)
# more reference can be found in mini_exchange package
TT.add_close_signal(4,close_status=-1)
TT.add_close_signal(-4,close_status=-1)
# trade 10 dollars when opening position each time
uad=pd.DataFrame({'user_name':[user_name],'amt_type':0,'value':10})
TT.trade(uad)
print(TT.summary())
# to analysis in detail, get the account info and position info of user01
account,position=TT.get_user(user_name)
# more details can be found in mini_exchange package
account.plot_history(by_pct=True)
account.annual_return()
account.draw_down()
account.romad()
position.win_rate(dual=True)
position.log
# plot one pair
pair='0001.HK|0002.HK'
TT.plot_trade_pair(user_name,pair,k0=k0,k1=k1,k2=k2,window=window)

Instant simulation in HK market with Wind Api

Find New Pair

# initialize
from CointArbitrage.instant_with_wind import init_log
init_log('log.csv')

# last t trading days
from WindPy import w
from CointArbitrage.instant_with_wind import trading_times
w.start()
times=trading_times(w,length=60,text="TradingCalendar=HKEX")

# download adjusted close price up to yesterday
# price is kept in file price_yyyymmdd.csv with eachline as 'tickers,values'
# more can be found in RNWS package
from CointArbitrage.instant_with_wind import download_hist_price
tickers=['0001.HK','0002.HK','0003.HK'...]
download_hist_price(tickers,times,'price_path',w)

# read in history price
from RNWS import read_df
hist_price=read_df('price_path',file_pattern='price',dt_range=times)

# filter stationary pairs
from CointArbitrage.pairing_period import filter_pval
import pandas as pd
pairs=['0001.HK|0002.HK','0001.HK|0003.HK',...]
new_pairs=filter_pval(hist_price,pairs,n_jobs=-1)
new_tickers=pd.Series(new_pairs).str.split('|',expand=True).unstack().unique().tolist()
new_hist=hist_price[new_tickers]

# lotsize and shortability
ls=pd.DataFrame({'shortable':[0,0,1,...],'lotsize':[500,1000,500,...]},index=['0001.HK','0002.HK','0003.HK'...])

# find new pairs
from CointArbitrage.instant_with_wind import find_new_hk
params={'log_path':'log.csv'
        ,'hist_price':hist_price
        ,'hist_log': pd.read_csv('history_log.csv') #from back test
        ,'pairs':new_pairs
        ,'tickers':new_tickers
        ,'zs_window':20
        ,'zs_log':False
        ,'w':w
        ,'ls':ls
        ,'potential_path':'potential_path.csv'
        ,'potential_k':1.8
        ,'k0':1
        ,'k1':2
        ,'k1':4
        ,'match_max':50000
        }

# update log.csv
sign=find_new_hk(**params)

update file every 1800s at trading hour and refresh evrey 900s at lunch break and before trading start

from CointArbitrage.instant_with_wind import time_sleep
time_sleep(sign={0:1800,1:900,2:'break',3:'break'})(find_new_hk)(**params)

Refresh log and check close status

params2={}
for key in ['log_path','hist_price','w','hist_log','k0','k2','plot_mark','potential_path','zs_log','zs_window']:
    params2.update(params[key])
refresh_hk(**params2)
# to continue refresh every 1800s
time_sleep(sign={0:1800,1:900,2:'break',3:'break'})(refresh_hk)(**params2)

Check stationarity by using the price at last 10min of all trading hours

param3={}
for key in ['log_path','hist_price','w','zs_window','zs_log','k0','k1']
    param3.update(key)
time_sleep(sign={0:10,1:9000,2:'break',3:'break'})(last_hk)(**param3)

Notice: After using time_sleep, sleep loops will start directly. Thus find_new, refresh and last should be running in 3 different consules.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for CointArbitrage, version 0.0.63
Filename, size File type Python version Upload date Hashes
Filename, size CointArbitrage-0.0.63-py3-none-any.whl (21.9 kB) File type Wheel Python version py3 Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page