加入一些咚咚

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

python
# -*- 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()

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

python
  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',