Monday, July 16, 2018

Python Run一下神經網路(Lstm)

之前說的神經網路可行性??


run300輪

來run一下別人大神級的code,裡面大神已經都出不介紹lstm大概是什麼了,小白只能runrun別人寫好的code
好code不run嗎?,這樣看下來好像只是根據原始的資料,後幾天才放馬後炮,我們當然要預測當天的阿,真的能預測當然就是神明了,之前有看過大神run出來的57%準度也是蠻狂的
之前也說過,我們不要來做它們那種,我們做部分的行為預測,那些要比數據量,專業度一般的人也拿不到那麼多的資料,我們來做小範圍的行為預知就好(做不出來)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense, Activation
from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY,YEARLY
from matplotlib.finance import quotes_historical_yahoo_ohlc, candlestick_ohlc
#import matplotlib
import tushare as ts
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pylab import date2num
import datetime
import numpy as np
from pandas import DataFrame
from numpy import row_stack,column_stack
import pandas
df=ts.get_hist_data('601857',start='2016-06-15',end='2018-01-12')
dd=df[['open','high','low','close']]
#print(dd.values.shape[0])
dd1=dd .sort_index()
dd2=dd1.values.flatten()
dd3=pandas.DataFrame(dd1['close'])
def load_data(df, sequence_length=10, split=0.8):
#df = pd.read_csv(file_name, sep=',', usecols=[1])
#data_all = np.array(df).astype(float)
data_all = np.array(df).astype(float)
scaler = MinMaxScaler()
data_all = scaler.fit_transform(data_all)
data = []
for i in range(len(data_all) - sequence_length - 1):
data.append(data_all[i: i + sequence_length + 1])
reshaped_data = np.array(data).astype('float64')
#np.random.shuffle(reshaped_data)
# 对x进行统一归一化,而y则不归一化
x = reshaped_data[:, :-1]
y = reshaped_data[:, -1]
split_boundary = int(reshaped_data.shape[0] * split)
train_x = x[: split_boundary]
test_x = x[split_boundary:]
train_y = y[: split_boundary]
test_y = y[split_boundary:]
return train_x, train_y, test_x, test_y, scaler
def build_model():
# input_dim是输入的train_x的最后一个维度,train_x的维度为(n_samples, time_steps, input_dim)
model = Sequential()
model.add(LSTM(input_dim=1, output_dim=6, return_sequences=True))
#model.add(LSTM(6, input_dim=1, return_sequences=True))
#model.add(LSTM(6, input_shape=(None, 1),return_sequences=True))
"""
#model.add(LSTM(input_dim=1, output_dim=6,input_length=10, return_sequences=True))
#model.add(LSTM(6, input_dim=1, input_length=10, return_sequences=True))
model.add(LSTM(6, input_shape=(10, 1),return_sequences=True))
"""
print(model.layers)
#model.add(LSTM(100, return_sequences=True))
#model.add(LSTM(100, return_sequences=True))
model.add(LSTM(100, return_sequences=False))
model.add(Dense(output_dim=1))
model.add(Activation('linear'))
model.compile(loss='mse', optimizer='rmsprop')
return model
def train_model(train_x, train_y, test_x, test_y):
model = build_model()
try:
model.fit(train_x, train_y, batch_size=512, nb_epoch=300, validation_split=0.1)
predict = model.predict(test_x)
predict = np.reshape(predict, (predict.size, ))
except KeyboardInterrupt:
print(predict)
print(test_y)
print(predict)
print(test_y)
try:
fig = plt.figure(1)
plt.plot(predict, 'r:')
plt.plot(test_y, 'g-')
plt.legend(['predict', 'true'])
except Exception as e:
print(e)
return predict, test_y
if __name__ == '__main__':
#train_x, train_y, test_x, test_y, scaler = load_data('international-airline-passengers.csv')
train_x, train_y, test_x, test_y, scaler =load_data(dd3, sequence_length=10, split=0.8)
train_x = np.reshape(train_x, (train_x.shape[0], train_x.shape[1], 1))
test_x = np.reshape(test_x, (test_x.shape[0], test_x.shape[1], 1))
predict_y, test_y = train_model(train_x, train_y, test_x, test_y)
predict_y = scaler.inverse_transform([[i] for i in predict_y])
test_y = scaler.inverse_transform(test_y)
fig2 = plt.figure(2)
plt.plot(predict_y, 'g:')
plt.plot(test_y, 'r-')
plt.show()
view raw lstm.py hosted with ❤ by GitHub

後來再來看一下,是不是訓練次數不夠?我們來加到1000輪

構思


會不會要針對某個特別情況進行訓練呢,在我們進行上一次的初步構想的篩選股票的咚咚
設定參數尋找BBand寬度特別寬的海選,接下來我們只要針對特殊買賣點做lstm做訓練,來修正買賣點以來提升初入金額?
忘記加scorllbar
這些大概就是篩選下來的股票我們來印證一下
寬度確實在20以上
要規避情況
初步我想進行,一檔股票裡所有波動度寬度>=20%在excel
應該是尋找特徵點,我像做的也就是最後面再加入規避正確後的一欄??
話說規避正確後幹嘛再用lstm??增加準度嗎還是??脫褲子放屁?,外行人只能試看看,找code run修修改改,與黃金交叉有什麼關聯,或者是kd??,正規好像不是這樣搞,異常弔詭
不斷的修正買賣點用來提升獲利最大化??亂講別噴
  1. 海撈BBand寬度大於20
  2. 再用excel在計算新的參考數值
  3. 制定tensorflow模型(異常困難)
  4. 訓練
精準的修正買賣點好了,每天海選20檔固定買賣,重要的是有本啦,以量制勝不過沒關西
xq可以有模擬帳戶,這如果成功我們再來tick資料來串
ㄎㄎ沒辦法,一整個很動態xd,沒辦法透過記憶體方式取得tick否則,可以用這個軟體,幫我們分擔基礎的網路負擔,還是透過封包?當然會加密阿xd,證券台灣的開通要
貴送送,最後想到來爬蟲一下發現某c股市交易模擬交易網站可以拿得每秒tick,不是每分鐘喔喔喔喔到時再來做小爬蟲和即時技術分析吧!新名詞蝶式套利波動度交易??好像是很多人吃飯工具?

Saturday, July 14, 2018

Pyhton 股票回測繪製BBand與爬蟲

繪製BBand與爬蟲


技術指標用的好,也要批量選股,我們先來看初步繪圖成果吧新增了選擇檔案,稍微改了一下介面,等等批量股票篩選(暫不小心用太多執行續被官網鎖IPQQ




BBAND.py


BBand=get_BBand()
BBand_up=[float(x) for x in BBand [0]]
BBand_sma=[float(x) for x in BBand [1]]
BBand_down=[float(x) for x in BBand [2]]
BBand_mid=[]
BBand_width=[]
for x in range(0,len(BBand_sma),1):
BBand_mid.append((BBand_up[x]+BBand_down[x])/2)
for x in range(0,len(BBand_mid),1):
BBand_width.append(100*((BBand_up[x]-BBand_down[x])/BBand_mid[x]))
view raw BBand.py hosted with ❤ by GitHub

爬蟲與篩選


#近三個月 bb寬度篩選
# 建立 5 個子執行緒
threads = []
for x in range (1000,9000,10):
for i in range(10):
threads.append(threading.Thread(target = job, args = (x+i,)))
threads[i].start()
print (i)
# 等待所有子執行緒結束
for i in range(10):
threads[i].join()
print (x+i)
threads.clear()
# 子執行緒的工作函數
def job(num):
# global catch_stock
# tmp=''
# if(get_historical_data(str(num)+'.TW', 90)>20):
# catch_stock.append(str(num)+'.TW')
# tmp=str(num)+'.TW'
print (get_historical_data(str(num)+'.TW', 90))
def get_historical_data(name, number_of_days):
max_bb=0
data = []
url = "https://finance.yahoo.com/quote/" + name + "/history/"
try:
rows = BeautifulSoup(urllib.request.urlopen(url).read()).findAll('table')[0].tbody.findAll('tr')
for each_row in rows:
divs = each_row.findAll('td')
if divs[1].span.text != 'Dividend': #Ignore this row in the table
#I'm only interested in 'Open' price; For other values, play with divs[1 - 5]
date_process=divs[0].span.text.replace(",", "")
date_process=datetime.strptime(date_process, '%b %d %Y').date().strftime('%Y/%m/%d')
t = date_process.replace('/','-')
date_process = (dates.date2num(datetime.strptime(t, '%Y-%m-%d')))
#date_process=datetime.datetime.strptime(date_process, '%b %d %Y').date().strftime('%m %d %Y')
#data.append({'Date': str(date_process), 'Open': float(divs[1].span.text.replace(',',''))\
# , 'High': float(divs[2].span.text.replace(',',''))\
# , 'Low': float(divs[3].span.text.replace(',',''))\
# , 'Close': float(divs[4].span.text.replace(',',''))\
# , 'Volume': float(divs[6].span.text.replace(',',''))})
#datas2 = (dates.date2num(datetime.strptime(t, '%Y-%m-%d')) , ope[x], high[x], low[x],close[x],vol[x])#
data.append([ str(date_process), float(divs[1].span.text.replace(',',''))\
, float(divs[2].span.text.replace(',',''))\
, float(divs[3].span.text.replace(',',''))\
, float(divs[4].span.text.replace(',',''))\
, float(divs[6].span.text.replace(',',''))])
#篩選指標
date.clear()
low.clear()
high.clear()
close.clear()
ope.clear()
vol.clear()
for x in data:
date.append(x[0])
ope.append(x[1])
high.append(x[2])
low.append(x[3])
close.append(x[4])
vol.append(x[5])
date.reverse()
low.reverse()
high.reverse()
close.reverse()
ope.reverse()
vol.reverse()
BBand=get_BBand()
BBand_up=[float(x) for x in BBand [0]]
BBand_sma=[float(x) for x in BBand [1]]
BBand_down=[float(x) for x in BBand [2]]
BBand_mid=[]
BBand_width=[]
for x in range(0,len(BBand_sma),1):
BBand_mid.append((BBand_up[x]+BBand_down[x])/2)
for x in range(0,len(BBand_mid),1):
BBand_width.append(100*((BBand_up[x]-BBand_down[x])/BBand_mid[x]))
#print (BBand_width)
#print (max(BBand_width[20:]))
print ('----------')
#if(max(BBand_width[20:]))
#return data[:number_of_days]
max_bb=max(BBand_width[20:])
#print (max(BBand_width[20:]))
except Exception as e:
#print ('找不到所選資料,或發生異常錯誤.')
max_bb=0
print (max_bb)
return max_bb
view raw BBand_catch.py hosted with ❤ by GitHub

像我想爬近三個月的成交量異常!?的股票,爬下來在分析再串自動下單!?,當然也要夠本,交易策略濾網要非常嚴謹,就可以放在家自動交易!?(後果不負責xd

多執行緒下次調10個好了,這次不知道要被鎖幾天,被當成ddos囉

換連手機一下
快像了快像了

下次目標


假設經過一票海選後,像是成交量阿還是要搜尋什麼類型的技術指標阿等等等等,我們可以把爬蟲後的資料,下再下來或倒入資料庫,下次爬蟲的時候我們只要爬,最近一筆再把他家進資料庫,這樣就可以下次不必再依賴yahoo資料庫,直接對自己資料庫要資料,我們不只可以用tick來做高頻交易(還要串api交易,你相信中華電信的網路嗎xdd,等等打造一個看盤軟體,或向xq操盤大師那樣什麼策略警示,等等,至於資料量的多寡,恩恩自己去爬吧xd ,接下來我們初步就完成一個最最最最基本的自動交易軟體的雛型囉,那麼ai真的真的真的要要來看一下囉,ㄎㄎ我會不會被一堆賣課程的針對‵,應該不會它們應該更有技術含量!

Wednesday, July 11, 2018

Pyhton 股票回測與MACD(二)

加入一些咚咚





左右對照圖
睡醒看到這個真的不是很開心rrr

以後要盯盤的時候,看了文字圖形看不慣吧?,我們來加入一些新元素,畫圖均線,標註買賣點好了,回測,績效等等介面化等等,我們可以看,近期內一定要完成ai,先完成專題在讀研究所?



# -*- coding: utf-8 -*-
"""
Created on Wed Dec 20 17:46:15 2017
@author: user
"""
from tkinter import *
from tkinter import messagebox
import tkinter as tk
import random
from tkinter import HORIZONTAL
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
import pandas as pd
import csv
import talib
import os
import time
import matplotlib.pyplot as plt
from mpl_finance import candlestick_ohlc
from mpl_finance import volume_overlay3
import matplotlib.dates as dates
from datetime import datetime
plt.rcParams['font.sans-serif'] = ['DFKai-sb']
plt.rcParams['font.family']='sans-serif'
#技術指標
def get_MACD():
MACD = talib.MACD(np.array(close),
fastperiod=12, slowperiod=26, signalperiod=9)
return [float(x) for x in MACD [1]]
def get_DIF():
DIF=[]
EMA12=talib.EMA(np.array(close), timeperiod=12)
EMA26=talib.EMA(np.array(close), timeperiod=26)
for tmp in range(0,len(EMA12)):
DIF.append(float(EMA12[tmp]-EMA26[tmp]))
return DIF
def get_OSC(macd,dif):
OSC=[]
for tmp in range(0,len(macd),1):
OSC.append(float(macd[tmp]-dif[tmp]))
return OSC
data_list = []
data_list2 = []
buy_list=[]
sell_list=[]
num_48 = ["1216統一"]
df=pd.DataFrame()
df2=pd.DataFrame(num_48)
for iii in num_48:
path_str=os.path.join("C:\\","Users","x2132","OneDrive","桌面","History_data",iii)
path_str=path_str+'.csv'
print (path_str)
#收盤
with open(path_str,'r') as c:
reader=csv.DictReader(c)
c=[row["收盤"] for row in reader] #要導入的列
#開盤
with open(path_str,'r') as o:
reader=csv.DictReader(o)
o=[row["開盤"] for row in reader] #要導入的列
#最高
with open(path_str,'r') as h:
reader=csv.DictReader(h)
h=[row["最高"] for row in reader] #要導入的列
#最低
with open(path_str,'r') as l:
reader=csv.DictReader(l)
l=[row["最低"] for row in reader] #要導入的列
#成交量
with open(path_str,'r') as v:
reader=csv.DictReader(v)
v=[row["成交量"] for row in reader] #要導入的列
#日期
with open(path_str,'r') as d:
reader=csv.DictReader(d)
d=[row["日期"] for row in reader] #要導入的列
ope = [float(x) for x in o]
close = [float(x) for x in c]
high = [float(x) for x in h]
low = [float(x) for x in l]
vol = [float(x)*0.0001 for x in v]
date =d
date_ex=[]
date.reverse()
low.reverse()
high.reverse()
close.reverse()
ope.reverse()
for x in range(0,len(ope),1):
#datess =dates.date2num(d[x])
#print (datetime.datetime(2017, 3, 13))
#print (dates.date2num(datetime.datetime(2017, 3, 13, 12, 0)))
#print (datetime.datetime(2017, 3, 13, 12, 0))
t = d[x].replace('/','-')
#print ((dates.date2num(datetime.strptime(t, '%Y-%m-%d'))))
# (type(datetime.datetime(2017, 3, 13, 12, 0)))
#print (type(dates.date2num(datetime.datetime(2017, 3, 13, 12, 0))))
#print(dates.date2num(datetime.datetime(2017, 3, 13, 12, 0)))
datas = (dates.date2num(datetime.strptime(t, '%Y-%m-%d')) , ope[x], high[x], low[x],close[x])
datas2 = (dates.date2num(datetime.strptime(t, '%Y-%m-%d')) , ope[x], high[x], low[x],close[x],vol[x])
date_ex.append(dates.date2num(datetime.strptime(t, '%Y-%m-%d')))
data_list.append(datas)
data_list2.append(datas2)
MACD=get_MACD()
DIF=get_DIF()
OSC=get_OSC(MACD,DIF)
#交易策略
start=0
end=len(data_list)
win=[]
win_con=[0]
los_con=[0]
buy_data=[]
self_data=[]
buy_date=[]
self_date=[]
star=100000 #一開始的錢
price=100000
handle=0 #持有股數
ex_handle=1 #持有股數上限
re_handle=0 #實際持有
for tmp in range(12,len(DIF),1):
if((tmp+1<len(DIF)) and tmp>start and tmp<end ):
print (tmp)
if(OSC[tmp]>=0 and price >= (ex_handle*close[tmp]*1000) ):
handle= handle+ex_handle*1000
re_handle=re_handle+ex_handle
fin_price=price-(ex_handle*ope[tmp+1])*1000 #1=1000
print ('買進日期',date[tmp+1],'開盤價',ope[tmp+1],'支出',(ex_handle*ope[tmp+1])*1000,'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle)
tmp_str='買進日期',date[tmp+1],'開盤價',ope[tmp+1],'支出',(ex_handle*ope[tmp+1])*1000,'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle
buy_data.append(tmp_str)
buy_list.append(data_list[tmp+1])
price= fin_price
elif (OSC[tmp]<0 and re_handle >=1 ):
fin_price=price+(re_handle*close[tmp])*1000
handle=0
re_handle=0
print ('賣出日期',date[tmp],'收盤價',close[tmp],'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle)
tmp_str='賣出日期',date[tmp],'收盤價',close[tmp],'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle
sell_list.append(data_list[tmp])
self_data.append(tmp_str)
price= fin_price
if (handle>0):#強制平倉
fin_price+= (close[len(close)-1]*handle)
handle=0
re_handle=0
print ('強制平倉 賣出日期',date[len(close)-1],'收盤價',close[len(close)-1],'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle)
#回測績效 - 交易次數
count=0
loss=0
for a,b in zip (buy_data[:],self_data[:]):
buy_date.append(a[3])
self_date.append(b[3])
if buy_date[0]<self_date[0]:
count+=1
else:
loss+=1
del buy_date[0]
del self_date[0]
for a,b in zip (buy_data[:],self_data[:]):
buy_date.append(a[3])
self_date.append(b[3])
if len(buy_date)>0:
z=(self_date[0]-buy_date[0])/buy_date[0]
if z>0:
win_con.append(z)
elif z<0:
los_con.append(z)
del buy_date[0]
del self_date[0]
print ('交易紀錄')
print ('-----------------------------------')
for tmp in buy_data:
print (tmp)
for tmp in self_data:
print (tmp)
wp=int(fin_price-star)
buy=len(buy_data)
sel=len(self_data)
total_trade=sum((len(buy_data),len(self_data)))
win_rate=round(count/sum((len(buy_data),len(self_data)))*100,2)
retur=round(((fin_price-star)/star)*100,2)
ave_retur=round((((fin_price-star)/star))/(sum((len(buy_data),len(self_data))))*100,4)
win_num=count
los_num=loss
max_win=round(max(win_con),2)
min_los=round(min(los_con),2)
data={"獲利金額":[wp],"買次數":[buy],"賣次數":[sel],"總交易次數":[total_trade],"勝率":[win_rate],"報酬率":[retur],"平均報酬率":[ave_retur],"獲利次數":[win_num],"虧損次數":[los_num],"最大獲利率":[max_win],"最大虧損率":[min_los]}
df=df.append(pd.DataFrame(data),ignore_index=True)
df.insert(0,'股票代號',df2)
df.to_csv("MACD.KPI.csv")
print ('獲利金額:',(int(fin_price-star)))
print ('交易次數 買/賣:',len(buy_data),'/',len(self_data))
print ('總交易次數:',sum((len(buy_data),len(self_data))))
print ('勝率:%5.2f'%(count/sum((len(buy_data),len(self_data)))*100),"%")
print ('報酬率:',round(((fin_price-star)/star)*100,2))
print ('報酬率:%5.2f'%(((fin_price-star)/star)*100),"%")
print ('平均報酬率',round((((fin_price-star)/star))/(sum((len(buy_data),len(self_data))))*100,4),"%")
print("獲勝次數:",count)
print("虧損次數:",loss)
print("最大獲利率:",round(max(win_con),2),"%")
print("最大虧損率:",round(min(los_con),2),"%")
# tmp2=10
# print (str(tmp2))
# tmp =type(tmp2)
# fig, ax = plt.subplots()
# print (fig)
# print (ax)
# fig.subplots_adjust(bottom=0.2)
# # 设置X轴刻度为日期时间
# #data_list.reverse()
# ax.xaxis_date()
# plt.xticks(rotation=45)
# plt.yticks()
# plt.title("k線圖")
# plt.xlabel("時間")
# plt.ylabel("股價")
# #print (len(data_list))
# candlestick_ohlc(ax, data_list[1000:2000], width=0.5, colorup='r', colordown='g')
# for x in range(0,len(buy_list),1):
# ax.annotate('', xy=(buy_list[x][0],buy_list[x][1]), xytext=(-15, -27),
# textcoords='offset points', ha="center",
# arrowprops=dict(facecolor='black', color='red',width=1),
# )
# for x in range(0,len(sell_list),1):
# ax.annotate('', xy=(sell_list[x][0],sell_list[x][1]), xytext=(-17, 20),
# textcoords='offset points', ha="center",
# arrowprops=dict(facecolor='black', color='green',width=1),
# )
# #print('hello')
# pro_fit='獲利金額:'+str((int(fin_price-star)))
# buy_count='交易次數 買/賣:'+str(len(buy_data))+'/'+str(len(self_data))
# plt.figtext(0.1,0.92,pro_fit+'\n'+buy_count,color='black')
# #plt.grid()
# plt.savefig("filename.png")
# #plt.show()
# print (buy_list[x][1])
# # print (buy_list)
# # print (MACD[500])
# # print (start)
# # print (end)
#畫圖區~~~~~~~~~
def show_info():
str_tmp='初始金額:'+str((int(star)))+"\n"+'獲利金額:'+str((int(fin_price-star)))+"\n"+'總收入金額:'+str((int(fin_price)))+"\n"+'交易次數 買/賣:'+str(len(buy_data))+'/'+str(len(self_data))+"\n"+'總交易次數:'+str(sum((len(buy_data),len(self_data))))+"\n"+'勝率:'+str((count/sum((len(buy_data),len(self_data)))*100))+'%'+"\n"+'報酬率:'+str(((fin_price-star)/star)*100)+'%'+"\n"+'平均報酬率:'+str(round((((fin_price-star)/star))/(sum((len(buy_data),len(self_data))))*100,4))+'%'+"\n"+'獲勝次數'+str(count)+"\n"+'虧損次數:'+str(loss)+"\n"+'最大獲利率:'+str(round(max(win_con),2))+'%'+"\n"+'最大虧損率:'+str(round(min(los_con),2))+'%'
tk.messagebox.showinfo("績效",str_tmp)
def clock():
t=time.strftime('%I:%M:%S',time.localtime())
if t!='':
var5.set(date[int(var.get())])
var6.set(date[int(var2.get())])
root.after(500,clock)
def drawPic():
try:sampleCount=int(inputEntry.get())
except:
sampleCount=50
inputEntry.delete(0,END)
inputEntry.insert(0,'50')
drawPic.f.clf()
drawPic.a =drawPic.f.add_axes([0.1,0.4,0.8,0.5])
drawPic.a2 = drawPic.f.add_axes([0.1,0.190,0.8,0.2])
drawPic.f.subplots_adjust(hspace=0)
drawPic.f.tight_layout()
drawPic.a.xaxis_date()
drawPic.a2.xaxis_date()
for label in drawPic.a.xaxis.get_ticklabels():
label.set_rotation(45)
for label in drawPic.a2.xaxis.get_ticklabels():
label.set_rotation(45)
drawPic.a.set_title("K線圖", fontsize=20)
drawPic.a2.set_xlabel("時間", fontsize=10)
drawPic.a.set_ylabel("股價", fontsize=10)
drawPic.a2.set_ylabel("成交量", fontsize=10)
# 设置X轴刻度为日期时间
#data_list.reverse()
sma_5 = talib.SMA(np.array(close), 5)
sma_10 = talib.SMA(np.array(close), 10)
sma_20 = talib.SMA(np.array(close), 20)
#print (len(data_list))
start =int(var.get())
end=int(var2.get())
if(var4.get()==1):
drawPic.a.plot( date_ex[start:end:5],sma_5[start:end:5], label='SMA5')
drawPic.a.plot( date_ex[start:end:10],sma_10[start:end:10], label='SMA10')
drawPic.a.plot( date_ex[start:end:20],sma_20[start:end:20], label='SMA20')
drawPic.a.legend(loc='upper left')
var5.set(date[start])
var6.set(date[end])
candlestick_ohlc(drawPic.a, data_list[start:end], width=0.5, colorup='r', colordown='g')
print (vol)
volume_overlay3(drawPic.a2,data_list2[start:end], colorup='r', colordown='g', width=0.5, alpha=0.8)
if(var3.get()==1):
for x in range(0,len(buy_list),1):
drawPic.a.annotate('', xy=(buy_list[x][0],buy_list[x][1]), xytext=(-15, -27),
textcoords='offset points', ha="center",
arrowprops=dict(facecolor='black', color='green',width=0.5),
)
for x in range(0,len(sell_list),1):
drawPic.a.annotate('', xy=(sell_list[x][0],sell_list[x][1]), xytext=(-17, 20),
textcoords='offset points', ha="center",
arrowprops=dict(facecolor='black', color='red',width=0.5),
)
drawPic.a.grid()
drawPic.a2.grid()
drawPic.canvas.show()
root=tk.Tk()
tk.Button(root,text='回測',command=drawPic).grid(row=1,column=2,columnspan=3)
tk.Button(root,text='績效',command=show_info).grid(row=2,column=2,columnspan=3)
drawPic.f = Figure(figsize=(15,7))
drawPic.canvas = FigureCanvasTkAgg(drawPic.f, master=root)
drawPic.canvas.show()
drawPic.canvas.get_tk_widget().grid(row=0, columnspan=3)
_job = None
var = DoubleVar(root,0)
var2 = DoubleVar(root,0)
var3 = tk.IntVar(root,0)
var4 = tk.IntVar(root,0)
var5 = tk.StringVar(root,0)
var6 = tk.StringVar(root,0)
w=tk.Scale(root, from_=start, to=end-1, orient=HORIZONTAL, variable = var ).grid(row=2,column=0)
w2=tk.Scale(root, from_=start, to=end-1, orient=HORIZONTAL, variable = var2).grid(row=2,column=1)
c1 = tk.Checkbutton(root, text='買賣點', variable=var3, onvalue=1, offvalue=0,
).grid(row=3,column=2)
c2 = tk.Checkbutton(root, text='KD線', variable=var4, onvalue=1, offvalue=0,
).grid(row=4,column=2)
tk.Label(root,text='请输入样本数量:').grid(row=1,column=0)
inputEntry=tk.Entry(root)
inputEntry.grid(row=1,column=1)
inputEntry.insert(0,'50')
data_label = tk.Label(root, text='-----', textvariable=var5).grid(row=3,column=0)
data_label2 = tk.Label(root, text='-----', textvariable=var6).grid(row=3,column=1)
clock()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))
root.mainloop()
view raw macd2.py hosted with ❤ by GitHub

原生成交量真的畫很醜我們來改造一下


原生,土砲一下

for x in data_list2[start:end]:
if((x[1]-x[4])<0):
pos_d.append(x[0])
pos_v.append(x[5])
elif ((x[1]-x[4])>0):
neg_d.append(x[0])
neg_v.append(x[5])
drawPic.a2.bar(pos_d,pos_v,color='green',width=1,align='center')
drawPic.a2.bar(neg_d,neg_v,color='red',width=1,align='center')
#drawPic.a2.bar(pos[0][0],pos[0][1],color='green',width=1,align='center')
#print (tupleto_listtmp)
# for x in pos:
# drawPic.a2.bar(x[0],x[1],color='green',width=1,align='center')
#for x in neg:
# drawPic.a2.bar(x[0],x[1],color='red',width=1,align='center')
#drawPic.a2.bar(pos[:][0],pos[:][1],color='green',width=1,align='center')
#drawPic.a2.bar(neg[:][0],neg[:][1],color='red',width=1,align='center')
#volume_overlay3(drawPic.a2,data_list2[start:end], colorup='r', colordown='g',
view raw volume.py hosted with ❤ by GitHub

Thursday, July 5, 2018

Pyhton 股票回測與MACD

回測一波


這次小研究可能要探討,中短期的技術指標,我想假設15天到30天採用不同的技術主標結算後,假設報酬率,不是最高的則,退回尋找最高回傳的報酬率,這段時間並輸出這段時間的,DATA可以詳細分析這段時間到底出了什麼事資料量越多或許可以結合ai作權重的提升,讓程式在適當的時機做出勝率最高的判斷,我想ai大概是這樣吧?!,這是下一次的目標
改得也不錯吧!?,樓下xq操盤高手


# -*- coding: utf-8 -*-
"""
Created on Wed Dec 20 17:46:15 2017
@author: user
"""
import numpy as np
import pandas as pd
import csv
import talib
import os
import time
import matplotlib.pyplot as plt
from mpl_finance import candlestick_ohlc
import matplotlib.dates as dates
from datetime import datetime
data_list = []
num_48 = ["1216統一"]
df=pd.DataFrame()
df2=pd.DataFrame(num_48)
for iii in num_48:
str=os.path.join("C:\\","Users","x2132","OneDrive","桌面","History_data",iii)
str=str+'.csv'
print (str)
#收盤
with open(str,'r') as c:
reader=csv.DictReader(c)
c=[row["收盤"] for row in reader] #要導入的列
#開盤
with open(str,'r') as o:
reader=csv.DictReader(o)
o=[row["開盤"] for row in reader] #要導入的列
#最高
with open(str,'r') as h:
reader=csv.DictReader(h)
h=[row["最高"] for row in reader] #要導入的列
#最低
with open(str,'r') as l:
reader=csv.DictReader(l)
l=[row["最低"] for row in reader] #要導入的列
#日期
with open(str,'r') as d:
reader=csv.DictReader(d)
d=[row["日期"] for row in reader] #要導入的列
ope = [float(x) for x in o]
close = [float(x) for x in c]
high = [float(x) for x in h]
low = [float(x) for x in l]
date =d
for x in range(0,len(ope),1):
#datess =dates.date2num(d[x])
#print (datetime.datetime(2017, 3, 13))
#print (dates.date2num(datetime.datetime(2017, 3, 13, 12, 0)))
#print (datetime.datetime(2017, 3, 13, 12, 0))
t = d[x].replace('/','-')
#print ((dates.date2num(datetime.strptime(t, '%Y-%m-%d'))))
# (type(datetime.datetime(2017, 3, 13, 12, 0)))
#print (type(dates.date2num(datetime.datetime(2017, 3, 13, 12, 0))))
#print(dates.date2num(datetime.datetime(2017, 3, 13, 12, 0)))
datas = (dates.date2num(datetime.strptime(t, '%Y-%m-%d')) , ope[x], high[x], low[x],close[x])
data_list.append(datas)
date.reverse()
low.reverse()
high.reverse()
close.reverse()
ope.reverse()
#技術指標
def get_MACD():
MACD = talib.MACD(np.array(close),
fastperiod=12, slowperiod=26, signalperiod=9)
return [float(x) for x in MACD [1]]
def get_DIF(test):
EMA12=talib.EMA(np.array(close), timeperiod=12)
EMA26=talib.EMA(np.array(close), timeperiod=26)
for tmp in range(0,len(EMA12)):
test.append(float(EMA12[tmp]-EMA26[tmp]))
DIF=[]
TRUE_MACD=get_MACD()
get_DIF(DIF)
#交易策略
win=[]
win_con=[0]
los_con=[0]
buy_data=[]
self_data=[]
buy_date=[]
self_date=[]
star=10000000 #一開始的錢
price=10000000
handle=0 #持有股數
ex_handle=1 #持有股數上限
re_handle=0 #實際持有
for tmp in range(12,len(DIF)):
if(tmp+1<len(DIF)):
if(DIF[tmp]>TRUE_MACD[tmp] and price >= (ex_handle*close[tmp]*1000) ):
handle= handle+ex_handle*1000
re_handle=re_handle+ex_handle
fin_price=price-(ex_handle*ope[tmp+1])*1000 #1=1000
print ('買進日期',date[tmp+1],'開盤價',ope[tmp+1],'支出',(ex_handle*ope[tmp+1])*1000,'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle)
str='買進日期',date[tmp+1],'開盤價',ope[tmp+1],'支出',(ex_handle*ope[tmp+1])*1000,'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle
buy_data.append(str)
elif (DIF[tmp]<TRUE_MACD[tmp] and re_handle >=1 ):
fin_price=price+(re_handle*close[tmp])*1000
handle=0
re_handle=0
print ('賣出日期',date[tmp],'收盤價',close[tmp],'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle)
str='賣出日期',date[tmp],'收盤價',close[tmp],'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle
self_data.append(str)
if (handle>0):#強制平倉
fin_price+= (close[len(close)-1]*handle)
handle=0
re_handle=0
print ('強制平倉 賣出日期',date[len(close)-1],'收盤價',close[len(close)-1],'結算金額',fin_price,'持有股數',handle,'持有張數',re_handle)
#回測績效 - 交易次數
count=0
loss=0
for a,b in zip (buy_data[:],self_data[:]):
buy_date.append(a[3])
self_date.append(b[3])
if buy_date[0]<self_date[0]:
count+=1
else:
loss+=1
del buy_date[0]
del self_date[0]
for a,b in zip (buy_data[:],self_data[:]):
buy_date.append(a[3])
self_date.append(b[3])
if len(buy_date)>0:
z=(self_date[0]-buy_date[0])/buy_date[0]
if z>0:
win_con.append(z)
elif z<0:
los_con.append(z)
del buy_date[0]
del self_date[0]
for tmp in buy_data:
print (tmp)
for tmp in self_data:
print (tmp)
wp=int(fin_price-star)
buy=len(buy_data)
sel=len(self_data)
total_trade=sum((len(buy_data),len(self_data)))
win_rate=round(count/sum((len(buy_data),len(self_data)))*100,2)
retur=round(((fin_price-star)/star)*100,2)
ave_retur=round((((fin_price-star)/star))/(sum((len(buy_data),len(self_data))))*100,4)
win_num=count
los_num=loss
max_win=round(max(win_con),2)
min_los=round(min(los_con),2)
data={"獲利金額":[wp],"買次數":[buy],"賣次數":[sel],"總交易次數":[total_trade],"勝率":[win_rate],"報酬率":[retur],"平均報酬率":[ave_retur],"獲利次數":[win_num],"虧損次數":[los_num],"最大獲利率":[max_win],"最大虧損率":[min_los]}
df=df.append(pd.DataFrame(data),ignore_index=True)
df.insert(0,'股票代號',df2)
df.to_csv("MACD.KPI.csv")
print ('獲利金額:',(int(fin_price-star)))
print ('交易次數 買/賣:',len(buy_data),'/',len(self_data))
print ('總交易次數:',sum((len(buy_data),len(self_data))))
print ('勝率:%5.2f'%(count/sum((len(buy_data),len(self_data)))*100),"%")
print ('報酬率:',round(((fin_price-star)/star)*100,2))
print ('報酬率:%5.2f'%(((fin_price-star)/star)*100),"%")
print ('平均報酬率',round((((fin_price-star)/star))/(sum((len(buy_data),len(self_data))))*100,4),"%")
print("獲勝次數:",count)
print("虧損次數:",loss)
print("最大獲利率:",round(max(win_con),2),"%")
print("最大虧損率:",round(min(los_con),2),"%")
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)
# 设置X轴刻度为日期时间
ax.xaxis_date()
plt.xticks(rotation=45)
plt.yticks()
plt.title("k線圖")
plt.xlabel("時間")
plt.ylabel("股價")
print (len(data_list))
candlestick_ohlc(ax, data_list[:], width=0.6, colorup='r', colordown='g')
print('hello')
plt.grid()
plt.show()
print (data_list)
view raw macd.py hosted with ❤ by GitHub

Wednesday, July 4, 2018

買個分享器




造型是很酷,動態指向訊號增強??基本上涵蓋率不錯,有時會當機,不知是誰的錯呢要使用AP好像才不會那麼容易斷線錯覺?