import csv #輸入import輸出export,輸入csv套件 import math #輸入math套件 from tkinter import * #或者import tkinter as tk scale = 2000 # 放大倍率 base = 600 # 圖形中心高度 def transposeMatrix(m): #自訂轉置transpose函數 N = [] for j in range(len(m[0])): row = [] for i in range(len(m)): row.append(m[i][j]) N.append(row) return N def getMatrixMinor(m,i,j): return [row[:j] + row[j+1:] for row in (m[:i]+m[i+1:])] def getMatrixDeternminant(m): #base case for 2x2 matrix if len(m) == 2: return m[0][0]*m[1][1]-m[0][1]*m[1][0] determinant = 0 for c in range(len(m)): determinant += ((-1)**c)*m[0][c]*getMatrixDeternminant(getMatrixMinor(m,0,c)) return determinant def getMatrixInverse(m): determinant = getMatrixDeternminant(m) if len(m) == 2: #處理2x2方陣 return [[m[1][1]/determinant, -1*m[0][1]/determinant], [-1*m[1][0]/determinant, m[0][0]/determinant]] cofactors = [] for r in range(len(m)): cofactorRow = [] for c in range(len(m)): minor = getMatrixMinor(m,r,c) cofactorRow.append(((-1)**(r+c))*getMatrixDeternminant(minor)) cofactors.append(cofactorRow) cofactors = transposeMatrix(cofactors) for r in range(len(cofactors)): for c in range(len(cofactors)): cofactors[r][c] = cofactors[r][c]/determinant return cofactors def draw_circle(x, y, label): canvas.create_oval(100+x-5, base-y-5, 100+x+5, base-y+5, fill="black") canvas.create_text(100+x+20, base-y, text=label, anchor='w', font=('微軟正黑體',20)) file = open('C:/Users/user/Downloads/20260521.csv','r',encoding='utf-8') read = csv.reader(file) header, rows = [], [] header = next(read) for item in read: rows.append(item) file.close() num = len(rows) #資料表長度,以下2603,2606,2609,2615,2637,00960,0050 mean, meanTemp= [0,0,0,0,0,0,0], [0,0,0,0,0,0,0] vari = [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] for k in range(num): for i in range(7): meanTemp[i]=float(rows[k][i+1])/100 #轉換為小數 mean[i] += meanTemp[i] for j in range(i+1): vari[i][j] += meanTemp[i]*meanTemp[j] for i in range(7): mean[i] = mean[i]/num for j in range(i+1): vari[i][j]=(vari[i][j] - mean[i]*mean[j]*num)/(num-1) for i in range(7): for j in range(i+1,7): vari[i][j]=vari[j][i] tk = Tk() #建構視窗名為tk tk.geometry('1200x900')#視窗 寬1200像素 tk.title("劉任昌分析航運股票日報酬")#第71與112列寫上自己的名字然後截圖 canvas = Canvas(tk, width=1200, height=900, bg='white') canvas.grid(row=0,column=0,padx=5,pady=5,columnspan=3) canvas.create_line(100, base, 1100, base, arrow=LAST,width=3) for i in range(1,8): #X軸 0 3 6 9 12 15 18 canvas.create_text(100+i*120, base, text = i*3, anchor='n', font=('微軟正黑體',20)) canvas.create_line(100, 800, 100, 50, arrow=LAST,width=3) for i in range(-3,7): #Y軸 -4 -3 -2 -1 0 1 2 3 4 canvas.create_text(94, base-i*80, text = i, anchor='e', font=('微軟正黑體',20)) canvas.create_text(1100, base+5, text = '標準差', anchor='n', font=('微軟正黑體',20)) canvas.create_text(95, 50, text = '報酬率', anchor='e', font=('微軟正黑體',20)) for i in range(7): x = math.sqrt(vari[i][i]*250)*scale y = 250*mean[i]*scale draw_circle(x, y, header[i+1] ) print(header[i+1], f"{x/scale:.4f}", f"{y/scale:.4f}") OmegaInverse = getMatrixInverse(vari[:5][:5]) #----------------2026/03/04增加計算GMV(GMV=Σ⁻¹ × 1/1' Σ⁻¹ 1) OmegaInverse就是Σ⁻¹ ones = [1,1,1,1,1] w_gmv = [0,0,0,0,0] for i in range(5): for j in range(5): w_gmv[i] += OmegaInverse[i][j] * ones[j] den = 0 for i in range(5): den += w_gmv[i] for i in range(5): w_gmv[i] = w_gmv[i] / den print("GMV weights:") for i in range(5): print(header[i+1], w_gmv[i]) # ---------畫 GMV 點--------- gmv_mean = 0 gmv_var = 0 for i in range(5): gmv_mean += w_gmv[i]*mean[i] for j in range(5): gmv_var += w_gmv[i]*vari[i][j]*w_gmv[j] gmv_y = 250*gmv_mean*scale gmv_x = math.sqrt(gmv_var*250)*scale canvas.create_text(100+gmv_x, base-gmv_y, text="★", fill="red", font=('Arial',28)) canvas.create_text(100+gmv_x-40, base-gmv_y+20, text="劉任昌GMV,Global Minimum Variance最小變異數投資組合", fill="red", font=('微軟正黑體',16)) ''' y_text = 120 canvas.create_text(900,y_text,text="GMV Weights",font=('Arial',16,'bold')) for i in range(6): txt = header[i+1] + " : " + format(w_gmv[i],".3f") canvas.create_text(900, y_text + (i+1)*30, text=txt, font=('Arial',14)) ''' A, B, C, D = 0, 0, 0, 0 for i in range(5): for j in range(5): A += mean[i]*OmegaInverse[i][j] B += mean[i]*OmegaInverse[i][j]*mean[j] C += OmegaInverse[i][j] D = B*C - A*A meanP = 0 while meanP <= 0.5: meanP += 0.00002 #效率前緣線密集度 y = 250*meanP*scale temp = meanP - A/C x = math.sqrt(250 * (C*temp*temp/D+1/C))*scale canvas.create_oval(100+x-1, base-y-1, 100+x+1, base-y+1, fill="red") ''' step = 0.1 w=[0,0,0,0,0,0] while w[0] <= 1: while w[0]+w[1] <= 1: while w[0]+w[1]+w[2] <= 1: while w[0]+w[1]+w[2]+w[3] <= 1: while w[0]+w[1]+w[2]+w[3]+w[4] <= 1: temp4=w[0]+w[1]+w[2]+w[3]+w[4] if temp4 < 1: w[5] = 1 - temp4 else: w[5] = 0 meanP, variP = 0, 0 for i in range(6): meanP += w[i]*mean[i] for j in range(6): variP += w[i]*vari[i][j]*w[j] y = 250*meanP*scale x = math.sqrt(variP*250)*scale canvas.create_oval(100+x-1,base-y-1, 100+x+1,base-y+1, fill="blue") w[4] += step w[3] += step w[4] = 0 w[2] += step w[3],w[4] = 0,0 w[1] += step w[2],w[3],w[4] = 0,0,0 w[0] += step w[1],w[2],w[3],w[4] = 0,0,0,0 ''' tk.mainloop()


留言

這個網誌中的熱門文章

德明科大財金系蘇柏丞衍生性金融商品銷售人員

蘇柏丞程式交易Markowitz 1952投資效率前緣