前回までで、遺伝子の抽出までが完成しました。
今回は抽出した遺伝子を使って、その後の推移を見ていこうと思います。
今回新しく書いたプログラムは、評価関数と同様のものを、より長期間回すようなプログラムです。
テストとして、株式1301コードのデータを使いました。
import random
import sys
from dataload_class import vstr2date
from dataload_class import dataload
import pylab
def geanInit(popSize):
#遺伝子の初期化
# popSize = 10 #個体数
geanLength = 10 #遺伝子長さ
pop = [] #個体
popGroup = []
kaiGean = [] #買い遺伝子
uriGean = [] #売り遺伝子
enki = 0 #-1or1
for i in range(popSize):
for j in range(geanLength):
enki = random.choice([-1,1])
kaiGean.append(enki)
for j in range(geanLength):
enki = random.choice([-1,1])
uriGean.append(enki)
pop.append(list(kaiGean))
pop.append(list(uriGean))
kaiGean =[]
uriGean = []
popGroup.append(list(pop))
pop =[]
# print popGroup
return popGroup
def predata_init():
code = 1301
data = dataload(code)
data = data.loadfile()
if data != 0:
t = vstr2date(data)
# print data[dataload.hajimene]
return [t, data[dataload.hajimene]]
def negative2zero(num):
if num<0:
num = 0
return num
def evalutionFunc(popGrope,popsize):
stockPrice = [] #株価
date = [] #日付
date,stockPrice = predata_init()
# print date,stockPrice
# popGrope = [[[-1, 1, -1, -1, 1, -1, -1, 1, -1, 1], [1, -1, -1, 1, 1, -1, 1, 1, 1, 1]], [[1, 1, 1, 1, 1, -1, -1, 1, 1, 1], [1, 1, -1, 1, 1, 1, 1, 1, -1, -1]], [[1, 1, 1, -1, -1, -1, -1, -1, 1, 1], [-1, 1, 1, 1, -1, 1, -1, -1, 1, 1]], [[-1, 1, 1, 1, -1, -1, 1, 1, -1, -1], [-1, -1, -1, 1, 1, -1, 1, -1, -1, -1]], [[-1, -1, 1, -1, 1, -1, 1, 1, -1, 1], [1, 1, -1, -1, 1, 1, -1, 1, -1, -1]], [[-1, 1, -1, -1, 1, 1, 1, 1, 1, 1], [-1, 1, -1, 1, -1, 1, 1, 1, -1, 1]], [[1, 1, 1, 1, 1, 1, -1, 1, -1, -1], [1, -1, 1, 1, -1, 1, -1, -1, -1, -1]], [[1, -1, -1, -1, 1, -1, -1, -1, 1, -1], [1, -1, -1, 1, -1, -1, 1, -1, 1, 1]], [[-1, 1, 1, 1, -1, 1, -1, -1, 1, 1], [1, -1, -1, -1, -1, 1, -1, 1, 1, 1]], [[1, -1, 1, -1, -1, -1, 1, -1, -1, 1], [-1, -1, 1, 1, 1, 1, 1, -1, -1, 1]]]
totalAssetsArry =[]
popnum = 0
for popnum in range(popsize):
# print popGrope
# print popnum
pop = list(popGrope[popnum])
kaiGean = pop[0]
uriGean = pop[1]
principal = 1000000 #元金(¥100万)
holding = 0 #持ち株量
#評価ループ
lenStockprice = len(stockPrice)
# print lenStockprice
fluctuationArry =[] #現在時間の評価配列を作る
today = lenStockprice - 100
agoArry =[0,1,2,3,5,8,13,21,35,56,89]
n=0
m=0
# print "--------------------------------------------------"
# print date[today]
for j in range(300):
todayPrice = stockPrice[today]
# print date[today]
# print todayPrice
for i in range(10):
n = agoArry[i]
m = agoArry[i+1]
# print n,m
ndayagoPrice = stockPrice[today + n] #n日前の株価
mdayagoPrice = stockPrice[today + m] #m日前の株価
changeValue =ndayagoPrice - mdayagoPrice
# print mdayagoPrice, date[today + m]
if changeValue<0:
fluctuationArry.append(-1)#小さかったら評価配列に-1追加
else:
fluctuationArry.append(1)
# print fluctuationArry
#ある地点での評価に使う配列完成
#評価配列と遺伝子の一致度を見る
# print kaiGean[7]
# print popGrope
kaiPoint =(negative2zero(fluctuationArry[0]*kaiGean[0])*18)+\
(negative2zero(fluctuationArry[1]*kaiGean[1])*16)+\
(negative2zero(fluctuationArry[2]*kaiGean[2])*14)+\
(negative2zero(fluctuationArry[3]*kaiGean[3])*12)+\
(negative2zero(fluctuationArry[4]*kaiGean[4])*10)+\
(negative2zero(fluctuationArry[5]*kaiGean[5])*10)+\
(negative2zero(fluctuationArry[6]*kaiGean[6])*8)+\
(negative2zero(fluctuationArry[7]*kaiGean[7])*6)+\
(negative2zero(fluctuationArry[8]*kaiGean[8])*4)+\
(negative2zero(fluctuationArry[9]*kaiGean[9])*2)
# print kaiPoint
if kaiPoint> 40:
# print principal,holding,todayPrice
holding = holding+ principal /todayPrice
principal = principal -(principal /todayPrice)*todayPrice
# print principal,holding,todayPrice
# print uriGean[7]
uriPoint =(negative2zero(fluctuationArry[0]*uriGean[0])*18)+\
(negative2zero(fluctuationArry[1]*uriGean[1])*16)+\
(negative2zero(fluctuationArry[2]*uriGean[2])*14)+\
(negative2zero(fluctuationArry[3]*uriGean[3])*12)+\
(negative2zero(fluctuationArry[4]*uriGean[4])*10)+\
(negative2zero(fluctuationArry[5]*uriGean[5])*10)+\
(negative2zero(fluctuationArry[6]*uriGean[6])*8)+\
(negative2zero(fluctuationArry[7]*uriGean[7])*6)+\
(negative2zero(fluctuationArry[8]*uriGean[8])*4)+\
(negative2zero(fluctuationArry[9]*uriGean[9])*2)
if uriPoint> 40:
# print "a",principal,holding
principal = principal +holding*todayPrice
holding = holding - holding
# print principal, holding
# print kaiPoint,uriPoint,principal,holding
fluctuationArry = []
today = today -1 #日付を進める
#評価ループ
totalAssets = principal + holding* todayPrice
# print totalAssets
# print date[today]
totalAssetsArry.append(totalAssets)
# print totalAssetsArry
return totalAssetsArry
def geanSelection(maxiter,elite,popsize,mutprob,popnum):
# maxiter = 1, 繰り返し数
# maximize = True, スコアを最大化
# popsize = 50, 個体数
# popnum = 10, 遺伝子数(長さ)
# elite = 0.2, 生き残る遺伝子の割合
# mutprob =0.2 突然変異のおこる確立
## maxiter = 100
## elite =0.2
## popsize =50
## mutprob=0.3
## popnum =10
popGrope =[]
#淘汰
def selection():
popScore = [(score[i],list(popGrope[i])) for i in range(popsize)]
popScore.sort()
popScore.reverse()
print popScore[0][0]
ranked = [v for (s,v) in popScore]
return ranked[:topelite]
# 突然変異
popSelect = 0
uriOrKai = 0
preMutGean = 0
afterMutEnki = 0
afterMutGean = 0
enkiSelect = 0
def mutant():
popSelect = random.SystemRandom().randint(0,len(popGrope)-1)
uriOrKai = random.SystemRandom().randint(0,1)
preMutGean = list(popGrope[popSelect][uriOrKai])
afterMutEnki = random.choice([-1,1])
enkiSelect = random.SystemRandom().randint(0,popnum-1)
afterMutGean = preMutGean[:enkiSelect] + [afterMutEnki] +\
preMutGean[enkiSelect+1:]
afterMutPop = list(popGrope[popSelect])
afterMutPop[uriOrKai] = afterMutGean
popGrope.append(afterMutPop)
# print preMutGean
# print afterMutGean
# 1点交叉 非推奨
# 2点交叉
uri = 0
kai = 1
kidPop =[uri,kai]
#2点交差
def twoPointCrossover(ma,fa):
i, j = sorted(random.SystemRandom().sample(range(popnum),2))
return random.SystemRandom().choice((ma[0:i] + fa[i:j] + ma[j:] , fa[0:i] + ma[i:j] + fa[j:]))
# 一様交叉
# 交叉アルゴリズムの選択
crossover = twoPointCrossover
# popGrope =[]
#遺伝子初期化
popGrope = geanInit(popsize)
# print popGrope
for k in range(maxiter):
#メインループ
#遺伝子評価
score = evalutionFunc(popGrope,popsize)
topelite = int(elite * popsize)
popGrope = selection() #淘汰
# print popGrope
while len(popGrope) < popsize:
if random.SystemRandom().random() < mutprob:
mutant() #突然変異
# print popGrope[0]
# print popGrope[1]
# print popGrope[2]
else:
#交差
#個体群から2匹抜き取る
while 1:
matherPop = random.SystemRandom().randint(0,len(popGrope)-1)
fatherPop = random.SystemRandom().randint(0,len(popGrope)-1)
# print matherPop,fatherPop
if matherPop != fatherPop:
break
#子供
selectCrossOver = random.SystemRandom().randint(0,1)
if selectCrossOver == 0:
#父母から1つずつ
while 1:
maOrFaUri = random.choice([matherPop,fatherPop])
maOrFaKai = random.choice([matherPop,fatherPop])
if maOrFaUri != maOrFaKai:
break
# print maOrFaUri,maOrFaKai
kidPop[uri] = list(popGrope[maOrFaUri][uri])
kidPop[kai] = list(popGrope[maOrFaKai][kai])
# print popGrope[maOrFaUri]
# print popGrope[maOrFaKai]
# print kidPop
if selectCrossOver == 1:
#1つずつもらって交差あり
kidPop[uri] = crossover(list(popGrope[matherPop][uri]),list(popGrope[fatherPop][uri]))
kidPop[kai] = crossover(list(popGrope[matherPop][kai]),list(popGrope[fatherPop][kai]))
# print kidPop
popGrope.append(kidPop)
# print popGrope
print "------------------------------------------------------",k
#メインループ
#score = evalutionFunc(popGrope,popsize)
#print score
score = evalutionFunc(popGrope,popsize)
print score
topelite = int(elite * popsize)
popGrope = selection()
return popGrope[0]
def main():
maxiter = 100
elite =0.1
popsize =100
mutprob=0.3
popnum =10
selectedPop = geanSelection(maxiter,elite,popsize,mutprob,popnum)
print selectedPop
stockPrice = [] #株価
date = [] #日付
date,stockPrice = predata_init()
# print date,stockPrice
# popGrope = [[[-1, 1, -1, -1, 1, -1, -1, 1, -1, 1], [1, -1, -1, 1, 1, -1, 1, 1, 1, 1]], [[1, 1, 1, 1, 1, -1, -1, 1, 1, 1], [1, 1, -1, 1, 1, 1, 1, 1, -1, -1]], [[1, 1, 1, -1, -1, -1, -1, -1, 1, 1], [-1, 1, 1, 1, -1, 1, -1, -1, 1, 1]], [[-1, 1, 1, 1, -1, -1, 1, 1, -1, -1], [-1, -1, -1, 1, 1, -1, 1, -1, -1, -1]], [[-1, -1, 1, -1, 1, -1, 1, 1, -1, 1], [1, 1, -1, -1, 1, 1, -1, 1, -1, -1]], [[-1, 1, -1, -1, 1, 1, 1, 1, 1, 1], [-1, 1, -1, 1, -1, 1, 1, 1, -1, 1]], [[1, 1, 1, 1, 1, 1, -1, 1, -1, -1], [1, -1, 1, 1, -1, 1, -1, -1, -1, -1]], [[1, -1, -1, -1, 1, -1, -1, -1, 1, -1], [1, -1, -1, 1, -1, -1, 1, -1, 1, 1]], [[-1, 1, 1, 1, -1, 1, -1, -1, 1, 1], [1, -1, -1, -1, -1, 1, -1, 1, 1, 1]], [[1, -1, 1, -1, -1, -1, 1, -1, -1, 1], [-1, -1, 1, 1, 1, 1, 1, -1, -1, 1]]]
totalAssetsArry =[]
popnum = 0
# print popGrope
# print popnum
pop = list(selectedPop)
kaiGean = pop[0]
uriGean = pop[1]
principal = 1000000 #元金(¥100万)
holding = 0 #持ち株量
principalStck =[]
holdingStck =[]
totalAssetsStck =[]
#評価ループ
lenStockprice = len(stockPrice)
# print lenStockprice
fluctuationArry =[] #現在時間の評価配列を作る
today = lenStockprice - 400
agoArry =[0,1,2,3,5,8,13,21,35,56,89]
n=0
m=0
# print "--------------------------------------------------"
# print date[today]
for j in range(lenStockprice-400):
todayPrice = stockPrice[today]
# print date[today]
# print todayPrice
for i in range(10):
n = agoArry[i]
m = agoArry[i+1]
# print n,m
ndayagoPrice = stockPrice[today + n] #n日前の株価
mdayagoPrice = stockPrice[today + m] #m日前の株価
changeValue =ndayagoPrice - mdayagoPrice
# print mdayagoPrice, date[today + m]
if changeValue<0:
fluctuationArry.append(-1)#小さかったら評価配列に-1追加
else:
fluctuationArry.append(1)
# print fluctuationArry
#ある地点での評価に使う配列完成
#評価配列と遺伝子の一致度を見る
# print kaiGean[7]
# print popGrope
kaiPoint =(negative2zero(fluctuationArry[0]*kaiGean[0])*18)+\
(negative2zero(fluctuationArry[1]*kaiGean[1])*16)+\
(negative2zero(fluctuationArry[2]*kaiGean[2])*14)+\
(negative2zero(fluctuationArry[3]*kaiGean[3])*12)+\
(negative2zero(fluctuationArry[4]*kaiGean[4])*10)+\
(negative2zero(fluctuationArry[5]*kaiGean[5])*10)+\
(negative2zero(fluctuationArry[6]*kaiGean[6])*8)+\
(negative2zero(fluctuationArry[7]*kaiGean[7])*6)+\
(negative2zero(fluctuationArry[8]*kaiGean[8])*4)+\
(negative2zero(fluctuationArry[9]*kaiGean[9])*2)
# print kaiPoint
if kaiPoint> 40:
# print principal,holding,todayPrice
holding = holding+ principal /todayPrice
principal = principal -(principal /todayPrice)*todayPrice
# print principal,holding,todayPrice
# print uriGean[7]
uriPoint =(negative2zero(fluctuationArry[0]*uriGean[0])*18)+\
(negative2zero(fluctuationArry[1]*uriGean[1])*16)+\
(negative2zero(fluctuationArry[2]*uriGean[2])*14)+\
(negative2zero(fluctuationArry[3]*uriGean[3])*12)+\
(negative2zero(fluctuationArry[4]*uriGean[4])*10)+\
(negative2zero(fluctuationArry[5]*uriGean[5])*10)+\
(negative2zero(fluctuationArry[6]*uriGean[6])*8)+\
(negative2zero(fluctuationArry[7]*uriGean[7])*6)+\
(negative2zero(fluctuationArry[8]*uriGean[8])*4)+\
(negative2zero(fluctuationArry[9]*uriGean[9])*2)
if uriPoint> 40:
# print "a",principal,holding
principal = principal +holding*todayPrice
holding = holding - holding
#print principal, holding
print principal,holding
# totalAssets = principal + holding* todayPrice
# totalAssetsStck.append(totalAssets)
principalStck.append(principal)
# holdingStck.append(holding)
fluctuationArry = []
today = today -1 #日付を進める
# print today
#評価ループ
totalAssets = principal + holding* todayPrice
# print totalAssets
# print date[today]
# totalAssetsArry.append(totalAssets)
print totalAssetsArry
pylab.plot(principalStck)
pylab.show()
# return totalAssetsArry
if __name__ == '__main__':
main()
実行結果は運がいいと、
(縦軸が資金で横軸が時間です。)
100万円が1200万円くらいになりました。
遺伝的アルゴリズムすごいですね。
ただ、長期的に見過ぎな気もしますのでそこが改善点ですかね。
また、他の銘柄だと全くダメなときもあります。
例えば2712(スターバックス)なんかは
うまくいくと、
うまくいかないと、
この辺を調節するにはいろいろな人工知能の勉強をしないといけませんかね。
改善点としては、閾値の最適化や、現在は売り買いで全財産を一気に使っているので、
売り買いする量も調整していきたいと思います。
また、遺伝子の重み付けのやり方ももっといい方法があると思いますので、
そこも改善したいと思います。
と、改善することだらけですが、
これで遺伝的アルゴリズムを使ったコードが完成しましたので、
次回からはニューラルネットワークで作ってみようかなと思います。



0 件のコメント:
コメントを投稿