로드 중...
검색 중...
일치하는 항목 없음
markowitz.py
이 파일의 문서로 이동하세요.
1
10
11가져오기os
12가져오기sys
13from수학가져오기
14가져오기matplotlib.pyplotasplt
15from게임가져오기GamsModifier, GamsWorkspace
16frompathlib가져오기경로
17가져오기셔틸
18
19GAMS_MODEL ="""
20설정
21s '선택된 주식'
22upper(s,s) '코바르 행렬의 일부'
23lower(s,s) '코바르 행렬의 일부';
24
25별칭(s,t);
26
27매개변수
28'일일 수익률 평균'을 의미합니다.
29covar(s,s) '수익률의 공분산 행렬(상위)';
30
31$데이터가 설정되지 않은 경우 $abort '제공된 데이터 파일에 대한 포함 파일 이름이 없습니다'
32$gdxIn %data%
33$load s covar 상하 평균
34$gdxIn
35
36변수
37z '객관 변수'
38ret '반환'
39var '분산'
40x(s) '투자';
41
42양수 변수 x;
43
44수식
45obj '목적'
46예산
47varcon '변동 제약조건'
48retcon '반환 제약';
49
50스칼라 람다 / 0 /;
51
52obj.. z =e= 람다*ret - (1-람다)*var;
53
54예산.. 합계(s, x(s)) =e= 1.0;
55
56varcon.. var =e= sum(upper(s,t), x(s)*covar(s,t)*x(t)) +
57sum(lower(s,t), x(s)*covar(t,s)*x(t));
58
59retcon..ret =e= 합계(들, 평균(들)*x(들));
60
61모델 마코비츠 / 모두 /;
62"""
63
64if__name__ =="__main__":
65sys_dir = sys.argv[1]iflen(sys.argv) > 1그밖에 없음
66work_dir = sys.argv[2]iflen(sys.argv) > 2그밖에 "."
67ws = GamsWorkspace(system_directory=sys_dir,working_directory=work_dir)
68
69작업 = ws.add_job_from_string(GAMS_MODEL)
70opt = ws.add_options()
71opt.all_model_types ="conopt"
72
73shutil.copy(
74경로(ws.system_directory,"api파일", "데이터", "markowitz.gdx"),
75경로(ws.working_directory,"markowitz.gdx"),
76 )
77
78markowitz_path = 경로(ws.working_directory,"markowitz.gdx").resolve()
79opt.defines["데이터"] = f'"markowitz_path"'
80
81cp = ws.add_checkpoint()
82job.run(opt, cp)
83mi = cp.add_modelinstance()
84l = mi.sync_db.add_parameter("람다", 0,"")
85mi.instantiate("markowitz는 nlp max z를 사용합니다", GamsModifier(l))
86
87 # 데이터 포인트 수집을 위한 목록
88data_points = []
89
90 # 최소 및 최대 수익 얻기 (lambda=0/1)
91l.add_record().value = 0
92mi.solve()
93min_ret = mi.sync_db["ret"].first_record().level
94data_points.append((min_ret, mi.sync_db["var"].first_record().level))
95l.first_record().value = 1
96mi.solve()
97max_ret = mi.sync_db["ret"].first_record().level
98data_points.append((max_ret, mi.sync_db["var"].first_record().level))
99
100 # 두 데이터 포인트 사이의 최대 거리(반환)를 지정하는 간격
101간격 = 0.02
102
103 # 간격 목록(스택), 여기서 간격은 두 개의 데이터 포인트를 포함하는 2-튜플로 표시됩니다.
104 # 각각은 2-튜플로 표현됨(람다, 리턴)
105간격 = [((0.0, min_ret), (1.0, max_ret))]
106
107 # 여러 람다 값에 대한 모델 인스턴스를 해결하는 알고리즘
108 # 부드러운 그래프를 얻기 위해 두 데이터 포인트 사이의 최대 간격을 사용
109 # 람다는 데이터 포인트의 균일한 분포를 위해 동적으로 계산됩니다.
110 그동안간격:
111 # 첫 번째 간격을 선택하고 람다의 새 값을 계산합니다.
112i = 간격.팝()
113min_l, min_ret = i[0][0], i[0][1]
114max_l, max_ret = i[1][0], i[1][1]
115
116l_val = (min_l + max_l) / 2
117l.first_record().value = l_val
118
119 # 새로운 람다 값으로 모델 인스턴스를 해결
120mi.solve()
121
122 # 반환 및 차이 결과 검색
123cur_ret = mi.sync_db["ret"].first_record().level
124data_points.append((cur_ret, mi.sync_db["var"].first_record().level))
125
126 # 간격이 여전히 큰 경우 새 간격을 추가
127 iffabs(cur_ret - min_ret) > 간격:
128intervals.append(((min_l, min_ret), (l_val, cur_ret)))
129 iffabs(cur_ret - max_ret) > 간격:
130intervals.append(((l_val, cur_ret), (max_l, max_ret)))
131
132 # 데이터 포인트를 정렬하고 플롯 기능을 위한 두 개의 목록을 만듭니다
133data_points.sort(키=람다tup: tup[0])
134ret = [x[0]forxin데이터_포인트]
135var = [x[1]x데이터_포인트]
136plt.plot(ret, var, marker=".", 마커 크기=10)
137plt.xlabel("반환")
138plt.ylabel("변수")
139plt.savefig(경로(ws.working_directory,"그림"))