-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathposition_manager.py
More file actions
176 lines (145 loc) · 8.38 KB
/
position_manager.py
File metadata and controls
176 lines (145 loc) · 8.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
仓位管理器小工具
功能:计算投资仓位和分批策略
"""
import tkinter as tk
from tkinter import ttk, messagebox
import math
class PositionManager:
def __init__(self, root):
self.root = root
self.root.title("仓位管理器")
self.root.geometry("600x700")
self.root.resizable(False, False)
# 策略配置
self.strategies = {
"等比例法(适合趋势单)": {
"ratios": [0.4, 0.3, 0.3],
"description": "分批比例:40% → 30% → 30%\n\n第一次建仓用最大仓位的40%,然后等到价格回到设定区间,再加仓30%,最后一次30%。\n\n优点:早期有一定仓位参与,趋势延续收益大\n缺点:第一次进场如果方向错,压力会大"
},
"递减法(更稳健)": {
"ratios": [0.5, 0.3, 0.2],
"description": "分批比例:50% → 30% → 20%\n\n建仓先拿一半仓位,方向对了继续加,方向错了也能轻松止损。\n\n优点:后续加仓压力小,不容易套重仓\n缺点:后期加仓资金较少"
},
"金字塔法(逆向加码)": {
"ratios": [0.2, 0.3, 0.5],
"description": "分批比例:20% → 30% → 50%\n\n一开始轻仓,确认方向正确(突破/反弹成立)后加码最大的一笔。\n\n优点:趋势确认后加大投入\n缺点:如果信号假突破,损失会集中在最后一次加仓"
}
}
self.setup_ui()
def setup_ui(self):
# 主框架
main_frame = ttk.Frame(self.root, padding="20")
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
# 标题
title_label = ttk.Label(main_frame, text="仓位管理器", font=("Arial", 16, "bold"))
title_label.grid(row=0, column=0, columnspan=2, pady=(0, 20))
# 总资金输入
ttk.Label(main_frame, text="总资金:", font=("Arial", 12)).grid(row=1, column=0, sticky=tk.W, pady=5)
self.total_funds_var = tk.StringVar()
total_funds_entry = ttk.Entry(main_frame, textvariable=self.total_funds_var, font=("Arial", 12), width=20)
total_funds_entry.grid(row=1, column=1, sticky=tk.W, pady=5)
ttk.Label(main_frame, text="元", font=("Arial", 12)).grid(row=1, column=2, sticky=tk.W, pady=5)
# 仓位比例选择
ttk.Label(main_frame, text="仓位比例:", font=("Arial", 12)).grid(row=2, column=0, sticky=tk.W, pady=5)
self.position_ratio_var = tk.IntVar(value=50)
position_frame = ttk.Frame(main_frame)
position_frame.grid(row=2, column=1, columnspan=2, sticky=tk.W, pady=5)
self.position_scale = ttk.Scale(position_frame, from_=10, to=100, orient=tk.HORIZONTAL,
variable=self.position_ratio_var, length=200,
command=self.update_position_display)
self.position_scale.grid(row=0, column=0, padx=(0, 10))
self.position_label = ttk.Label(position_frame, text="50%", font=("Arial", 12, "bold"))
self.position_label.grid(row=0, column=1)
# 本次投资金额显示
ttk.Label(main_frame, text="本次投资金额:", font=("Arial", 12)).grid(row=3, column=0, sticky=tk.W, pady=5)
self.investment_amount_var = tk.StringVar(value="0 元")
investment_label = ttk.Label(main_frame, textvariable=self.investment_amount_var,
font=("Arial", 12, "bold"), foreground="blue")
investment_label.grid(row=3, column=1, sticky=tk.W, pady=5)
# 策略选择
ttk.Label(main_frame, text="选择策略:", font=("Arial", 12)).grid(row=5, column=0, sticky=tk.W, pady=5)
self.strategy_var = tk.StringVar()
strategy_combo = ttk.Combobox(main_frame, textvariable=self.strategy_var,
values=list(self.strategies.keys()),
state="readonly", font=("Arial", 11), width=25)
strategy_combo.grid(row=5, column=1, columnspan=2, sticky=tk.W, pady=5)
strategy_combo.bind('<<ComboboxSelected>>', self.on_strategy_selected)
# 策略说明
strategy_desc_frame = ttk.LabelFrame(main_frame, text="策略说明", padding="10")
strategy_desc_frame.grid(row=6, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=10)
self.strategy_desc_text = tk.Text(strategy_desc_frame, height=8, width=60,
font=("Arial", 10), wrap=tk.WORD, state=tk.DISABLED)
self.strategy_desc_text.grid(row=0, column=0, sticky=(tk.W, tk.E))
# 分批结果
result_frame = ttk.LabelFrame(main_frame, text="分批投资计算结果", padding="10")
result_frame.grid(row=7, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=10)
self.result_text = tk.Text(result_frame, height=6, width=60,
font=("Arial", 11), wrap=tk.WORD, state=tk.DISABLED)
self.result_text.grid(row=0, column=0, sticky=(tk.W, tk.E))
# 计算分批按钮
calc_batch_button = ttk.Button(main_frame, text="计算分批投资", command=self.calculate_batch,
style="Accent.TButton")
calc_batch_button.grid(row=8, column=0, columnspan=3, pady=20)
def update_position_display(self, value=None):
"""更新仓位比例显示"""
ratio = int(float(self.position_ratio_var.get()))
self.position_label.config(text=f"{ratio}%")
self.calculate_investment()
def calculate_investment(self):
"""计算本次投资金额"""
try:
total_funds = float(self.total_funds_var.get() or 0)
position_ratio = self.position_ratio_var.get() / 100
investment_amount = total_funds * position_ratio
self.investment_amount_var.set(f"{investment_amount:,.2f} 元")
except ValueError:
self.investment_amount_var.set("0 元")
def on_strategy_selected(self, event=None):
"""策略选择事件"""
strategy_name = self.strategy_var.get()
if strategy_name in self.strategies:
description = self.strategies[strategy_name]["description"]
self.strategy_desc_text.config(state=tk.NORMAL)
self.strategy_desc_text.delete(1.0, tk.END)
self.strategy_desc_text.insert(1.0, description)
self.strategy_desc_text.config(state=tk.DISABLED)
def calculate_batch(self):
"""计算分批投资"""
try:
total_funds = float(self.total_funds_var.get() or 0)
position_ratio = self.position_ratio_var.get() / 100
investment_amount = total_funds * position_ratio
strategy_name = self.strategy_var.get()
if not strategy_name:
messagebox.showwarning("警告", "请先选择投资策略!")
return
if investment_amount <= 0:
messagebox.showwarning("警告", "请输入有效的总资金!")
return
strategy = self.strategies[strategy_name]
ratios = strategy["ratios"]
result_text = f"策略:{strategy_name}\n"
result_text += f"总投资金额:{investment_amount:,.2f} 元\n"
result_text += "=" * 40 + "\n"
total_check = 0
for i, ratio in enumerate(ratios, 1):
batch_amount = investment_amount * ratio
total_check += batch_amount
result_text += f"第{i}批:{ratio*100:g}% = {batch_amount:,.2f} 元\n"
result_text += "=" * 40 + "\n"
result_text += f"合计:{total_check:,.2f} 元"
self.result_text.config(state=tk.NORMAL)
self.result_text.delete(1.0, tk.END)
self.result_text.insert(1.0, result_text)
self.result_text.config(state=tk.DISABLED)
except ValueError:
messagebox.showerror("错误", "请输入有效的数字!")
def main():
root = tk.Tk()
app = PositionManager(root)
root.mainloop()
if __name__ == "__main__":
main()