前回までで、遺伝子の抽出までが完成しました。
今回は抽出した遺伝子を使って、その後の推移を見ていこうと思います。
今回新しく書いたプログラムは、評価関数と同様のものを、より長期間回すようなプログラムです。
テストとして、株式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 件のコメント:
コメントを投稿