今回はこれらすべての要素を組み合わせて、遺伝子を選抜していこうと思います。
全体的な流れとしては、
遺伝子を初期化、評価、淘汰、突然変異もしくは交差を行い、
評価から交差までを繰り返します。
最初に元金として100000万円持たせていて、
これが300日で最も増加する遺伝子が最良のものとして選択します。
import random
import sys
from dataload_class import vstr2date
from dataload_class import dataload
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 main():
# maxiter = 1, 繰り返し数
# maximize = True, スコアを最大化
# popsize = 50, 個体数
# popnum = 10, 遺伝子数(長さ)
# elite = 0.2, 生き残る遺伝子の割合
# mutprob =0.2 突然変異のおこる確立
maxiter = 10
elite =0.2
popsize =10
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()
print popGrope[0]
if __name__ == '__main__':
main()
以上になります。これで、遺伝子を選択するプログラムが出来ました。
参考までに実行してみたところ、
1000000円が1443537円まで増加しました。
ご使用になる方は自己責任でお願いします。
次回はこの遺伝子を使って長期間での変化を見ていこうと思います。
0 件のコメント:
コメントを投稿