雨上がりの放物線

究極の三日坊主が居場所を見つけるまでの物語

7/31 Pythonによる分析法(雑)

Pythonとは

数理系に強いプログラミング言語、AQRというクオンツファンドの人が能力の拡張を頑張ったおかげで金融系で結構使われているらしい。

 

僕が今月ちまちま勉強してできるようにしたのは、2つです。

一つはセクター別の株価分析。セクターの中である程度規模が大きい(株価の値動きの激しく無い)銘柄を決めたら(ここまでは手作業、株マップとかで)、株価の取得及びcsvファイルへの記録、値動きの激しさ(標準偏差)、それをもとにした標準化、相関係数計算、相関係数の低い銘柄の排除、それらを基にして現在までの乖離率の推移をグラフに映し出す為のプログラムです。このプログラムに入力として銘柄コードを与えてやればカタカタ働いて結果を返してくれます。

これにはanalysis.pyと名付けました(pyはPythonプログラムの事)

analysis.py
import matplotlib.pyplot as plt
import numpy as np
from pandas import Series,DataFrame
import pandas.io.data as web
import datetime

all_data={}
def get_price(cards):
for ticker in cards:
all_data[ticker] = web.get_data_yahoo(ticker, (datetime.datetime.today() - datetime.timedelta(weeks = 208)), datetime.datetime.today())

price = DataFrame({tic: data["Adj Close"]
for tic, data in all_data.items()})
return price


def get_each_sigma(price,cards):
sigma = [np.std(price[x]) for x in cards]
sigmadatas = Series(sigma, index=cards)
return sigmadatas

def normalize(price,cards):
sigma = get_each_sigma(price,cards)
for i in cards:
price[i] /= sigma[i]
norm = np.average(price[cards[0]])

for i in cards[1:]:
price[i] = price[i] - np.average(price[i]) + norm

def remove(price,cards,corrnorm=0.8):
corr0 = price.corrwith(price[cards[0]])

for i in cards[1:]:
if corr0[i] < corrnorm:
print(i + " is not appropriate.")
price = price.drop(i, axis=1)
cards = cards.remove(i)
return price

def add_index(price,cards):
average = DataFrame({"index" : price.sum(axis = 1)/len(cards)}) # should be improved
return price.join(average)

def show_graph(price):
plt.figure()
price.plot()
plt.show()

def dev_past(price, cards):
dev = price.copy()
for i in cards:
dev[i] = (dev[i] - dev["index"])/dev["index"]

dev["index"] = 0
return dev

もう一つは投資配分を出力するプログラム。入力としてanalysisの結果用いる事にした銘柄群、それとリアルタイムの株価(これを手に入れる方法はわかりませんでした)を入れる事で現在の乖離率を計算し、それぞれ買うべき、あるいは売るべき単位数を返してくれます。こちらはdecision.pyです。

import analysis
import numpy as np
import pandas as pd
import datetime

all_data = {}
def get_now(p,cards): #use new signals
for i in range(len(p)):
all_data[cards[i]] = p[i]
return all_data

def dev_n(all_data, price, cards): #use new price and cards
sigma = analysis.get_each_sigma(price, cards)

for i in cards:
all_data[i] /= sigma[i]
price[i] /= sigma[i]


norm = np.average(price[cards[0]])

for i in cards:
all_data[i] = all_data[i] - np.average(price[i]) + norm
print(all_data)
sum = 0
for i in cards:
sum += all_data[i]
sum /= len(all_data)
all_data["index"] = sum

dev={}
for i in cards:
dev[i] = (all_data[i] - all_data["index"]) / all_data["index"]

dev["index"] = 0
return dev

def inv_n(dev,cards, norm = 0.04):
inv = {}
s = 0
l = 0
for i in cards: #make s and l
if dev[i] >= norm:
s += dev[i]
elif dev[i] <= -norm:
l -= dev[i]
else: pass

for i in cards:
if dev[i] >= norm:
inv[i] = -dev[i]/s
elif dev[i] <= -norm:
inv[i] = -dev[i]/l
else: inv[i] = 0
return inv

def number_rate(all_data,inv,cards):
num_rate = {}
min = 1
for i in cards:
num_rate[i] = inv[i]/all_data[i]
if num_rate[i] != 0 and abs(num_rate[i]) <= min:
min = abs(num_rate[i])
else: pass
for i in cards:
num_rate[i] = num_rate[i]/min *100
return num_rate

あとはそれらのスイッチを入れるプログラムさえあればOKです。今回は米国株のアセットマネジメントセクターを用いてプログラムを書いたのでAMA(Asset Management Analysis)とAMD(Asset Management Decision)と名付けました。

AMA.py

import analysis

cards = ["BLK","AMP","BK","BX","IVZ","NTRS","STT","TROW"]

price = analysis.get_price(cards)
print(price)
price.to_csv("AMPrice.csv")
analysis.normalize(price, cards)

price = analysis.add_index(price,cards)

dev = analysis.dev_past(price, cards)

dev.to_csv("AMDev.csv")
analysis.show_graph(dev)

AMD.py

import decision
import pandas as pd

cards = ["BLK","AMP","BK","BX","IVZ","NTRS","STT","TROW"]
p = [356.58,96.38,39.71,25.30,27.60,67.11,57.46,74.08]

price = pd.read_csv("AMPrice.csv")
data = decision.get_now(p,cards)
print(data)

dev = decision.dev_n(data, price, cards)
print(dev)
inv = decision.inv_n(dev,cards)
num_rate = decision.number_rate(data,inv,cards)
print(num_rate)

コードだけ乗っけても不親切なので次から2回に分けてanalysisとdecisionを解説する会を作りますね。出来るかなー。