StockChartDemo 项目分析¶
项目信息¶
- 项目名称: StockChartDemo
- 下载链接: StockChartDemo.rar
- 分析时间: 2026-05-17
运行截图¶

文件结构¶
StockChartDemo/
├── DATA/ # 股票数据目录
│ └── 日K线/ # 日K线数据文件
│ ├── 00_加权.DAT
│ ├── 01_金融.DAT
│ ├── 02_电子.DAT
│ ├── 03_非金融.DAT
│ ├── 04_非电子.DAT
│ ├── 05_联电.DAT
│ ├── 06_台积电.DAT
│ ├── 07_华邦.DAT
│ ├── 08_明基.DAT
│ ├── 09_宏碁.DAT
│ ├── 10_华硕.DAT
│ ├── 11_友达.DAT
│ └── 12_奇美.DAT
├── Extractor_Icon.ico
├── fDemo.py # 主窗体代码
├── fDemo.pydfm # 窗体设计文件(二进制)
├── fDemo.sct # 设计文件(事件声明)
├── fDemo.sfm # 窗体结构文件
├── Project1.py # 项目主程序
└── Project1.xml # 项目配置文件
主程序文件: Project1.py¶
from glcl import *
from fDemo import *
def main():
icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Extractor_Icon.ico")
if not os.path.exists(icon_path):
print('Extractor_Icon.ico is missing. Do not delete or rename this file.')
return
Application.Initialize()
Application.Title = 'Project1'
Application.MainFormOnTaskbar = True
Application.Icon.LoadFromFile(icon_path)
MainForm = frmDemo(Application)
MainForm.Show()
FreeConsole()
Application.Run()
MainForm.Free()
if __name__ == '__main__':
main()
单元文件: fDemo.py¶
# Powered By Python Studio, The best Python GUI IDE to download from glsite.com.
import os # 导入操作系统模块,用于文件路径操作
from glcl import * # 导入glcl框架的所有组件
class frmDemo(Form): # 定义主窗体类,继承自Form
'''TStockChart Demo - Stock chart viewer application''' # 类说明:股票图表查看器应用程序
def __init__(self, owner): # 构造函数,初始化窗体
self.splitter = Splitter(self) # 分隔条控件
self.pnlTop = Panel(self) # 顶部面板
self.lblStock = Label(self) # 股票代码标签
self.lblStatus = Label(self) # 状态信息标签
self.edtStock = Edit(self) # 股票代码输入框
self.btnLoad = Button(self) # "加载"按钮
self.btnZoomIn = Button(self) # "放大"按钮
self.btnZoomOut = Button(self) # "缩小"按钮
self.btnFirst = Button(self) # "跳转到第一条"按钮
self.btnLeft = Button(self) # "向左滚动"按钮
self.btnRight = Button(self) # "向右滚动"按钮
self.btnLast = Button(self) # "跳转到最后一条"按钮
self.pnlLeft = Panel(self) # 左侧面板
self.grpDisplay = GroupBox(self) # "显示选项"分组框
self.chkMA = CheckBox(self) # "显示均线"复选框
self.chkVMA = CheckBox(self) # "显示成交量均线"复选框
self.chkDate = CheckBox(self) # "显示日期刻度"复选框
self.chkDot = CheckBox(self) # "显示虚线"复选框
self.chkHL = CheckBox(self) # "显示高低价标签"复选框
self.chkRSI = CheckBox(self) # "显示RSI面板"复选框
self.grpMA = GroupBox(self) # "均线周期设置"分组框
self.lblMA0 = Label(self) # 均线0的标签
self.lblMA1 = Label(self) # 均线1的标签
self.lblMA2 = Label(self) # 均线2的标签
self.lblMA3 = Label(self) # 均线3的标签
self.lblMA4 = Label(self) # 均线4的标签
self.lblMA5 = Label(self) # 均线5的标签
self.seMA0 = SpinEdit(self) # 均线0的数值调节控件
self.seMA1 = SpinEdit(self) # 均线1的数值调节控件
self.seMA2 = SpinEdit(self) # 均线2的数值调节控件
self.seMA3 = SpinEdit(self) # 均线3的数值调节控件
self.seMA4 = SpinEdit(self) # 均线4的数值调节控件
self.seMA5 = SpinEdit(self) # 均线5的数值调节控件
self.grpRSI = GroupBox(self) # "RSI周期设置"分组框
self.lblRSI0 = Label(self) # RSI0的标签
self.lblRSI1 = Label(self) # RSI1的标签
self.seRSI0 = SpinEdit(self) # RSI0的数值调节控件
self.seRSI1 = SpinEdit(self) # RSI1的数值调节控件
self.grpColor = GroupBox(self) # "颜色设置"分组框
self.btnBgColor = Button(self) # "背景颜色"按钮
self.btnUpColor = Button(self) # "上涨颜色"按钮
self.btnDnColor = Button(self) # "下跌颜色"按钮
self.btnEvColor = Button(self) # "平盘颜色"按钮
self.grpLayout = GroupBox(self) # "布局设置"分组框
self.lblKRatio = Label(self) # K线比例标签
self.lblVRatio = Label(self) # 成交量比例标签
self.trkKRatio = TrackBar(self) # K线比例滑块
self.trkVRatio = TrackBar(self) # 成交量比例滑块
self.grpInfo = GroupBox(self) # "信息显示"分组框
self.mmoInfo = Memo(self) # 信息显示文本框
self.pnlRight = Panel(self) # 右侧面板
self.grpList = GroupBox(self) # "股票列表"分组框
self.lstStocks = ListBox(self) # 股票列表控件
self.Chart = StockChart(self) # 核心的股票图表控件
self.ColorDlg = ColorDialog(self) # 颜色选择对话框
# 从.pydfm文件中加载窗体属性(位置、大小、字体等)
self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "fDemo.pydfm"))
# !!!!!!!!!!!!!!!!!!注意!!!!!!!!!!!!!!!!!!!!!
# 如果需要打包为EXE,需要在配置exe中附带打包DATA目录
# !!!!!!!!!!!!!!!!!!注意!!!!!!!!!!!!!!!!!!!!!
# 设置事件处理程序 - 首先绑定图表相关的事件
self.Chart.OnDataIndexChange = self.ChartDataIndexChange # 绑定数据索引变化事件
self.Chart.OnStockLoaded = self.ChartStockLoaded # 绑定股票加载完成事件
self.Chart.OnStockNotFound = self.ChartStockNotFound # 绑定股票未找到事件
# 绑定工具栏按钮事件
self.btnLoad.OnClick = self.btnLoadClick # 绑定"加载"按钮点击事件
self.btnZoomIn.OnClick = self.btnZoomInClick # 绑定"放大"按钮点击事件
self.btnZoomOut.OnClick = self.btnZoomOutClick # 绑定"缩小"按钮点击事件
self.btnFirst.OnClick = self.btnFirstClick # 绑定"跳转到第一条"按钮点击事件
self.btnLast.OnClick = self.btnLastClick # 绑定"跳转到最后一条"按钮点击事件
self.btnLeft.OnClick = self.btnLeftClick # 绑定"向左滚动"按钮点击事件
self.btnRight.OnClick = self.btnRightClick # 绑定"向右滚动"按钮点击事件
# 绑定显示选项复选框事件
self.chkMA.OnClick = self.chkMAClick # 绑定"显示均线"复选框点击事件
self.chkVMA.OnClick = self.chkVMAClick # 绑定"显示成交量均线"复选框点击事件
self.chkDate.OnClick = self.chkDateClick # 绑定"显示日期刻度"复选框点击事件
self.chkDot.OnClick = self.chkDotClick # 绑定"显示虚线"复选框点击事件
self.chkHL.OnClick = self.chkHLClick # 绑定"显示高低价标签"复选框点击事件
self.chkRSI.OnClick = self.chkRSIClick # 绑定"显示RSI面板"复选框点击事件
# 绑定均线周期数值调节控件事件(使用Tag属性区分不同的控件)
self.seMA0.Tag = 0 # 设置seMA0的标识为0
self.seMA1.Tag = 1 # 设置seMA1的标识为1
self.seMA2.Tag = 2 # 设置seMA2的标识为2
self.seMA3.Tag = 3 # 设置seMA3的标识为3
self.seMA4.Tag = 4 # 设置seMA4的标识为4
self.seMA5.Tag = 5 # 设置seMA5的标识为5
self.seMA0.OnChange = self.seMAChange # 绑定seMA0数值变化事件
self.seMA1.OnChange = self.seMAChange # 绑定seMA1数值变化事件
self.seMA2.OnChange = self.seMAChange # 绑定seMA2数值变化事件
self.seMA3.OnChange = self.seMAChange # 绑定seMA3数值变化事件
self.seMA4.OnChange = self.seMAChange # 绑定seMA4数值变化事件
self.seMA5.OnChange = self.seMAChange # 绑定seMA5数值变化事件
# 绑定RSI周期数值调节控件事件
self.seRSI0.Tag = 0 # 设置seRSI0的标识为0
self.seRSI1.Tag = 1 # 设置seRSI1的标识为1
self.seRSI0.OnChange = self.seRSIChange # 绑定seRSI0数值变化事件
self.seRSI1.OnChange = self.seRSIChange # 绑定seRSI1数值变化事件
# 绑定颜色选择按钮事件(使用Tag属性区分不同的按钮)
self.btnBgColor.Tag = 0 # 设置"背景颜色"按钮标识为0
self.btnUpColor.Tag = 1 # 设置"上涨颜色"按钮标识为1
self.btnDnColor.Tag = 2 # 设置"下跌颜色"按钮标识为2
self.btnEvColor.Tag = 3 # 设置"平盘颜色"按钮标识为3
self.btnBgColor.OnClick = self.btnColorClick # 绑定"背景颜色"按钮点击事件
self.btnUpColor.OnClick = self.btnColorClick # 绑定"上涨颜色"按钮点击事件
self.btnDnColor.OnClick = self.btnColorClick # 绑定"下跌颜色"按钮点击事件
self.btnEvColor.OnClick = self.btnColorClick # 绑定"平盘颜色"按钮点击事件
# 绑定布局滑块事件
self.trkKRatio.OnChange = self.trkKRatioChange # 绑定K线比例滑块变化事件
self.trkVRatio.OnChange = self.trkVRatioChange # 绑定成交量比例滑块变化事件
# 绑定股票列表选择事件
self.lstStocks.OnClick = self.lstStocksClick # 绑定股票列表点击事件
# 同步控件状态与图表默认值
self.SyncControls() # 将图表的当前属性值同步到所有UI控件上
# 扫描DATA文件夹获取股票列表
self.ScanStockList() # 扫描数据目录,将可用的股票文件添加到列表
# 如果存在股票,则加载默认股票
if self.lstStocks.Count > 0: # 判断股票列表是否不为空
self.lstStocks.ItemIndex = 0 # 选中列表中的第一项
self.edtStock.Text = self.lstStocks.Items[0] # 将股票代码填入输入框
self.Chart.LoadStock(self.edtStock.Text) # 加载默认股票数据
# ---------------------------------------------------------------------------
# SyncControls - 将图表属性值同步到UI控件
# ---------------------------------------------------------------------------
def SyncControls(self):
"""将图表的当前显示设置同步到对应的控件上"""
self.chkMA.Checked = self.Chart.ShowMA # 同步"显示均线"复选框状态
self.chkVMA.Checked = self.Chart.ShowVolumeMA # 同步"显示成交量均线"复选框状态
self.chkDate.Checked = self.Chart.ShowDateScale # 同步"显示日期刻度"复选框状态
self.chkDot.Checked = self.Chart.ShowDotLine # 同步"显示虚线"复选框状态
self.chkHL.Checked = self.Chart.ShowHighLowLabel # 同步"显示高低价标签"复选框状态
self.chkRSI.Checked = self.Chart.ShowRSI # 同步"显示RSI面板"复选框状态
self.seMA0.Value = int(self.Chart.GetMACycle(0)) # 同步均线0的周期值
self.seMA1.Value = int(self.Chart.GetMACycle(1)) # 同步均线1的周期值
self.seMA2.Value = int(self.Chart.GetMACycle(2)) # 同步均线2的周期值
self.seMA3.Value = int(self.Chart.GetMACycle(3)) # 同步均线3的周期值
self.seMA4.Value = int(self.Chart.GetMACycle(4)) # 同步均线4的周期值
self.seMA5.Value = int(self.Chart.GetMACycle(5)) # 同步均线5的周期值
self.seRSI0.Value = int(self.Chart.GetRSICycle(0)) # 同步RSI0的周期值
self.seRSI1.Value = int(self.Chart.GetRSICycle(1)) # 同步RSI1的周期值
self.trkKRatio.Position = int(float(self.Chart.KLineRatio) * 100) # 同步K线比例滑块位置(转换为百分比)
self.trkVRatio.Position = int(float(self.Chart.VolumeRatio) * 100) # 同步成交量比例滑块位置(转换为百分比)
# ---------------------------------------------------------------------------
# ScanStockList - 从 .\DATA\日K线\*.DAT 填充股票列表
# ---------------------------------------------------------------------------
def ScanStockList(self):
"""扫描数据文件目录,将所有.DAT文件添加到股票列表中"""
self.lstStocks.Clear() # 清空股票列表
DataDir = self.Chart.DataPath # 获取图表控件当前设置的数据路径
import sys
if not os.path.isdir(DataDir): # 如果数据目录不存在
# 尝试根据可执行文件所在位置定位数据目录
exe_dir = os.path.dirname(os.path.abspath(__file__))
DataDir = os.path.join(exe_dir, 'DATA', '日K线') + os.sep # 拼接为"DATA/日K线/"路径
self.Chart.DataPath = DataDir # 更新图表控件的数据路径
if os.path.isdir(DataDir): # 如果数据目录存在
for fname in os.listdir(DataDir): # 遍历目录下的所有文件
if fname.upper().endswith('.DAT'): # 只处理扩展名为.DAT的文件(不区分大小写)
name = os.path.splitext(fname)[0] # 去除扩展名,只保留文件名
self.lstStocks.Items.Add(name) # 将股票名称添加到列表框中
if self.lstStocks.Count == 0: # 如果没有找到任何股票数据文件
self.lstStocks.Items.Add('(no *.DAT found in ' + str(DataDir) + ')') # 显示提示信息
# ---------------------------------------------------------------------------
# 工具栏按钮事件处理方法
# ---------------------------------------------------------------------------
def btnLoadClick(self, Sender):
"""加载按钮点击事件 - 根据输入框中的股票代码加载股票数据"""
stock = self.edtStock.Text.strip() # 获取输入框中的股票代码并去除前后空格
if stock != '': # 如果股票代码不为空
self.Chart.LoadStock(stock) # 调用图表控件的LoadStock方法加载数据
def btnZoomInClick(self, Sender):
"""放大按钮点击事件 - 放大图表显示"""
self.Chart.ZoomIn() # 调用图表的放大方法
def btnZoomOutClick(self, Sender):
"""缩小按钮点击事件 - 缩小图表显示"""
self.Chart.ZoomOut() # 调用图表的缩小方法
def btnFirstClick(self, Sender):
"""跳转到第一条按钮点击事件 - 滚动到数据的第一条"""
self.Chart.ScrollToFirst() # 调用图表的滚动到第一条方法
def btnLastClick(self, Sender):
"""跳转到最后一条按钮点击事件 - 滚动到数据的最后一条"""
self.Chart.ScrollToLast() # 调用图表的滚动到最后一条方法
def btnLeftClick(self, Sender):
"""向左滚动按钮点击事件 - 向左滚动一屏"""
self.Chart.ScrollLeft(1) # 调用图表的向左滚动方法
def btnRightClick(self, Sender):
"""向右滚动按钮点击事件 - 向右滚动一屏"""
self.Chart.ScrollRight(1) # 调用图表的向右滚动方法
# ---------------------------------------------------------------------------
# 显示选项复选框事件处理方法
# ---------------------------------------------------------------------------
def chkMAClick(self, Sender):
"""显示均线复选框点击事件 - 切换均线显示"""
self.Chart.ShowMA = self.chkMA.Checked # 将复选框状态设置给图表的ShowMA属性
def chkVMAClick(self, Sender):
"""显示成交量均线复选框点击事件 - 切换成交量均线显示"""
self.Chart.ShowVolumeMA = self.chkVMA.Checked # 将复选框状态设置给图表的ShowVolumeMA属性
def chkDateClick(self, Sender):
"""显示日期刻度复选框点击事件 - 切换日期刻度显示"""
self.Chart.ShowDateScale = self.chkDate.Checked # 将复选框状态设置给图表的ShowDateScale属性
def chkDotClick(self, Sender):
"""显示虚线复选框点击事件 - 切换虚线显示"""
self.Chart.ShowDotLine = self.chkDot.Checked # 将复选框状态设置给图表的ShowDotLine属性
def chkHLClick(self, Sender):
"""显示高低价标签复选框点击事件 - 切换高低价标签显示"""
self.Chart.ShowHighLowLabel = self.chkHL.Checked # 将复选框状态设置给图表的ShowHighLowLabel属性
def chkRSIClick(self, Sender):
"""显示RSI面板复选框点击事件 - 切换RSI面板显示"""
self.Chart.ShowRSI = self.chkRSI.Checked # 将复选框状态设置给图表的ShowRSI属性
# ---------------------------------------------------------------------------
# 均线周期数值调节控件事件处理方法
# ---------------------------------------------------------------------------
def seMAChange(self, Sender):
"""均线周期数值变化事件 - 根据用户调整更新对应均线的周期值"""
SE = Sender # 获取触发事件的SpinEdit控件对象
self.Chart.SetMACycle(SE.Tag, int(SE.Value)) # 根据Tag标识和当前值设置对应均线的周期
# ---------------------------------------------------------------------------
# RSI周期数值调节控件事件处理方法
# ---------------------------------------------------------------------------
def seRSIChange(self, Sender):
"""RSI周期数值变化事件 - 根据用户调整更新对应RSI的周期值"""
SE = Sender # 获取触发事件的SpinEdit控件对象
self.Chart.SetRSICycle(SE.Tag, int(SE.Value)) # 根据Tag标识和当前值设置对应RSI的周期
# ---------------------------------------------------------------------------
# 颜色选择按钮事件处理方法
# ---------------------------------------------------------------------------
def btnColorClick(self, Sender):
"""颜色按钮点击事件 - 打开颜色选择对话框,设置图表的对应颜色"""
Btn = Sender # 获取触发事件的按钮对象
tag = Btn.Tag # 获取按钮的Tag标识
if tag == 0: # 如果Tag为0,表示背景颜色按钮
self.ColorDlg.Color = self.Chart.BackColor # 将对话框初始颜色设置为当前背景色
elif tag == 1: # 如果Tag为1,表示上涨颜色按钮
self.ColorDlg.Color = self.Chart.UpColor # 将对话框初始颜色设置为当前上涨色
elif tag == 2: # 如果Tag为2,表示下跌颜色按钮
self.ColorDlg.Color = self.Chart.DownColor # 将对话框初始颜色设置为当前下跌色
elif tag == 3: # 如果Tag为3,表示平盘颜色按钮
self.ColorDlg.Color = self.Chart.EvenColor # 将对话框初始颜色设置为当前平盘色
if self.ColorDlg.Execute(): # 显示颜色选择对话框,如果用户点击了"确定"
if tag == 0: # 背景颜色按钮
self.Chart.BackColor = self.ColorDlg.Color # 设置图表的背景颜色
elif tag == 1: # 上涨颜色按钮
self.Chart.UpColor = self.ColorDlg.Color # 设置图表的上涨颜色
elif tag == 2: # 下跌颜色按钮
self.Chart.DownColor = self.ColorDlg.Color # 设置图表的下跌颜色
elif tag == 3: # 平盘颜色按钮
self.Chart.EvenColor = self.ColorDlg.Color # 设置图表的平盘颜色
# ---------------------------------------------------------------------------
# 布局滑块事件处理方法
# ---------------------------------------------------------------------------
def trkKRatioChange(self, Sender):
"""K线比例滑块变化事件 - 调整K线图在图表中的显示比例"""
self.Chart.KLineRatio = float(self.trkKRatio.Position) / 100.0 # 将滑块位置值(0-100)转换为比例(0.0-1.0)
self.lblKRatio.Caption = 'K-Line: %d%%' % self.trkKRatio.Position # 更新显示K线比例的标签文本
def trkVRatioChange(self, Sender):
"""成交量比例滑块变化事件 - 调整成交量图在图表中的显示比例"""
self.Chart.VolumeRatio = float(self.trkVRatio.Position) / 100.0 # 将滑块位置值(0-100)转换为比例(0.0-1.0)
self.lblVRatio.Caption = 'Volume: %d%%' % self.trkVRatio.Position # 更新显示成交量比例的标签文本
# ---------------------------------------------------------------------------
# 股票列表事件处理方法
# ---------------------------------------------------------------------------
def lstStocksClick(self, Sender):
"""股票列表点击事件 - 选中股票后加载其数据到图表"""
idx = self.lstStocks.ItemIndex # 获取当前选中项的索引
if idx >= 0: # 如果选中了有效项
Name = self.lstStocks.Items[idx] # 获取选中的股票名称
if Name != '' and Name[0] != '(': # 排除提示信息(以括号开头的文本)
self.edtStock.Text = Name # 将股票名称填入输入框
self.Chart.LoadStock(Name) # 加载该股票的数据
# ---------------------------------------------------------------------------
# 图表事件处理方法
# ---------------------------------------------------------------------------
def ChartDataIndexChange(self, Sender, ADataIndex, AData):
"""图表数据索引变化事件 - 当前选中的K线数据发生变化时更新信息面板"""
self.UpdateInfoPanel(ADataIndex, AData) # 调用信息面板更新方法
def ChartStockLoaded(self, Sender, AStockName, ADataCount):
"""股票加载完成事件 - 更新状态栏显示加载成功信息"""
self.lblStatus.Caption = 'Loaded: %s (%s bars)' % (AStockName, str(ADataCount)) # 显示股票名称和数据条数
self.lblStatus.Font.Color = clLime # 将状态文字颜色设置为亮绿色(表示成功)
def ChartStockNotFound(self, Sender, AStockName):
"""股票未找到事件 - 更新状态栏显示错误信息"""
self.lblStatus.Caption = 'NOT FOUND: ' + str(AStockName) # 显示未找到的股票名称
self.lblStatus.Font.Color = clRed # 将状态文字颜色设置为红色(表示错误)
self.mmoInfo.Lines.Clear() # 清空信息面板
self.mmoInfo.Lines.Add('Data file not found for: ' + str(AStockName)) # 添加未找到数据文件的提示
self.mmoInfo.Lines.Add('Expected path: ' + str(self.Chart.DataPath) + str(AStockName) + '.DAT') # 显示期望的数据文件路径
# ---------------------------------------------------------------------------
# UpdateInfoPanel - 显示当前K线的OHLCV数据(开盘、最高、最低、收盘、成交量)
# ---------------------------------------------------------------------------
def UpdateInfoPanel(self, ADataIndex, AData):
"""更新信息面板 - 显示当前选中的K线数据(索引、日期、开盘价、最高价、最低价、收盘价、成交量)"""
self.mmoInfo.Lines.BeginUpdate() # 开始批量更新,提高性能并避免闪烁
try:
self.mmoInfo.Lines.Clear() # 清空信息文本框
self.mmoInfo.Lines.Add('Index : ' + str(ADataIndex)) # 显示当前数据索引
if AData is not None and hasattr(AData, 'Date') and AData.Date != 0: # 如果数据有效且日期不为0
self.mmoInfo.Lines.Add('Date : ' + str(AData.Date)) # 显示日期
self.mmoInfo.Lines.Add('Open : ' + str(AData.OP)) # 显示开盘价
self.mmoInfo.Lines.Add('High : ' + str(AData.HP)) # 显示最高价
self.mmoInfo.Lines.Add('Low : ' + str(AData.LP)) # 显示最低价
self.mmoInfo.Lines.Add('Close : ' + str(AData.CP)) # 显示收盘价
self.mmoInfo.Lines.Add('Volume: ' + str(AData.VOL)) # 显示成交量
self.mmoInfo.Lines.Add('') # 添加空行分隔
self.mmoInfo.Lines.Add('Total bars: ' + str(self.Chart.GetDataCount())) # 显示总数据条数
else: # 如果没有有效数据
self.mmoInfo.Lines.Add('(no record)') # 显示"无记录"提示
finally:
self.mmoInfo.Lines.EndUpdate() # 确保无论是否发生异常都结束批量更新
设计文件: fDemo.sct¶
def btnLoadClick(Sender):
def btnZoomInClick(Sender):
def btnZoomOutClick(Sender):
def btnFirstClick(Sender):
def btnLastClick(Sender):
def btnLeftClick(Sender):
def btnRightClick(Sender):
def chkMAClick(Sender):
def chkVMAClick(Sender):
def chkDateClick(Sender):
def chkDotClick(Sender):
def chkHLClick(Sender):
def chkRSIClick(Sender):
def seMAChange(Sender):
def seRSIChange(Sender):
def btnColorClick(Sender):
def trkKRatioChange(Sender):
def trkVRatioChange(Sender):
def lstStocksClick(Sender):
def ChartDataIndexChange(Sender, ADataIndex, AData):
def ChartStockLoaded(Sender, AStockName, ADataCount):
def ChartStockNotFound(Sender, AStockName):
设计文件: fDemo.sfm¶
object frmDemo: TfrmDemo
Left = 0
Top = 0
Caption = 'TStockChart Demo'
ClientHeight = 814
ClientWidth = 1180
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Tahoma'
Font.Style = []
Position = poDesigned
WindowState = wsMaximized
TextHeight = 14
object splitter: TSplitter
Left = 180
Top = 36
Width = 6
Height = 778
Color = clBtnFace
ParentColor = False
end
object pnlTop: TPanel
Left = 0
Top = 0
Width = 1180
Height = 36
Align = alTop
BevelOuter = bvNone
TabOrder = 0
object lblStock: TLabel
Left = 8
Top = 10
Width = 70
Height = 14
Caption = 'Stock Name:'
end
object lblStatus: TLabel
Left = 548
Top = 10
Width = 164
Height = 14
Caption = 'Ready. Load a stock to begin.'
Font.Charset = DEFAULT_CHARSET
Font.Color = clSilver
Font.Height = -12
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
end
object edtStock: TEdit
Left = 72
Top = 7
Width = 120
Height = 22
TabOrder = 0
end
object btnLoad: TButton
Left = 198
Top = 6
Width = 60
Height = 24
Caption = 'Load'
TabOrder = 1
end
object btnZoomIn: TButton
Left = 270
Top = 6
Width = 36
Height = 24
Caption = 'Z+'
TabOrder = 2
end
object btnZoomOut: TButton
Left = 308
Top = 6
Width = 36
Height = 24
Caption = 'Z-'
TabOrder = 3
end
object btnFirst: TButton
Left = 356
Top = 6
Width = 50
Height = 24
Caption = '|<<'
TabOrder = 4
end
object btnLeft: TButton
Left = 408
Top = 6
Width = 36
Height = 24
Caption = '<'
TabOrder = 5
end
object btnRight: TButton
Left = 446
Top = 6
Width = 36
Height = 24
Caption = '>'
TabOrder = 6
end
object btnLast: TButton
Left = 484
Top = 6
Width = 50
Height = 24
Caption = '>>|'
TabOrder = 7
end
end
object pnlLeft: TPanel
Left = 0
Top = 36
Width = 180
Height = 778
Align = alLeft
BevelOuter = bvNone
TabOrder = 1
object grpDisplay: TGroupBox
Left = 4
Top = 4
Width = 172
Height = 152
Caption = 'Display Options'
TabOrder = 0
object chkMA: TCheckBox
Left = 8
Top = 20
Width = 150
Height = 18
Caption = 'Show Price MA Lines'
Checked = True
State = cbChecked
TabOrder = 0
end
object chkVMA: TCheckBox
Left = 8
Top = 40
Width = 150
Height = 18
Caption = 'Show Volume MA Lines'
Checked = True
State = cbChecked
TabOrder = 1
end
object chkDate: TCheckBox
Left = 8
Top = 60
Width = 150
Height = 18
Caption = 'Show Date Scale'
Checked = True
State = cbChecked
TabOrder = 2
end
object chkDot: TCheckBox
Left = 8
Top = 80
Width = 150
Height = 18
Caption = 'Show Background Dotlines'
Checked = True
State = cbChecked
TabOrder = 3
end
object chkHL: TCheckBox
Left = 8
Top = 100
Width = 150
Height = 18
Caption = 'Show High/Low Labels'
Checked = True
State = cbChecked
TabOrder = 4
end
object chkRSI: TCheckBox
Left = 8
Top = 120
Width = 150
Height = 18
Caption = 'Show RSI Panel'
Checked = True
State = cbChecked
TabOrder = 5
end
end
object grpMA: TGroupBox
Left = 4
Top = 160
Width = 172
Height = 200
Caption = 'Price MA Periods'
TabOrder = 1
object lblMA0: TLabel
Left = 8
Top = 22
Width = 28
Height = 14
Caption = 'MA1:'
end
object lblMA1: TLabel
Left = 8
Top = 46
Width = 28
Height = 14
Caption = 'MA2:'
end
object lblMA2: TLabel
Left = 8
Top = 70
Width = 28
Height = 14
Caption = 'MA3:'
end
object lblMA3: TLabel
Left = 8
Top = 94
Width = 28
Height = 14
Caption = 'MA4:'
end
object lblMA4: TLabel
Left = 8
Top = 118
Width = 28
Height = 14
Caption = 'MA5:'
end
object lblMA5: TLabel
Left = 8
Top = 142
Width = 28
Height = 14
Caption = 'MA6:'
end
object seMA0: TSpinEdit
Left = 80
Top = 19
Width = 60
Height = 23
MaxValue = 500
MinValue = 0
TabOrder = 0
Value = 5
end
object seMA1: TSpinEdit
Tag = 1
Left = 80
Top = 43
Width = 60
Height = 23
MaxValue = 500
MinValue = 0
TabOrder = 1
Value = 10
end
object seMA2: TSpinEdit
Tag = 2
Left = 80
Top = 67
Width = 60
Height = 23
MaxValue = 500
MinValue = 0
TabOrder = 2
Value = 30
end
object seMA3: TSpinEdit
Tag = 3
Left = 80
Top = 91
Width = 60
Height = 23
MaxValue = 500
MinValue = 0
TabOrder = 3
Value = 60
end
object seMA4: TSpinEdit
Tag = 4
Left = 80
Top = 115
Width = 60
Height = 23
MaxValue = 500
MinValue = 0
TabOrder = 4
Value = 120
end
object seMA5: TSpinEdit
Tag = 5
Left = 80
Top = 139
Width = 60
Height = 23
MaxValue = 500
MinValue = 0
TabOrder = 5
Value = 240
end
end
object grpRSI: TGroupBox
Left = 4
Top = 364
Width = 172
Height = 72
Caption = 'RSI Periods'
TabOrder = 2
object lblRSI0: TLabel
Left = 8
Top = 22
Width = 29
Height = 14
Caption = 'RSI1:'
end
object lblRSI1: TLabel
Left = 8
Top = 46
Width = 29
Height = 14
Caption = 'RSI2:'
end
object seRSI0: TSpinEdit
Left = 80
Top = 19
Width = 60
Height = 23
MaxValue = 200
MinValue = 2
TabOrder = 0
Value = 5
end
object seRSI1: TSpinEdit
Tag = 1
Left = 80
Top = 43
Width = 60
Height = 23
MaxValue = 200
MinValue = 2
TabOrder = 1
Value = 10
end
end
object grpColor: TGroupBox
Left = 4
Top = 440
Width = 172
Height = 121
Caption = 'Colours'
TabOrder = 3
object btnBgColor: TButton
Left = 8
Top = 18
Width = 152
Height = 22
Caption = 'Background Colour'
TabOrder = 0
end
object btnUpColor: TButton
Tag = 1
Left = 8
Top = 44
Width = 152
Height = 22
Caption = 'Rising Bar Colour'
TabOrder = 1
end
object btnDnColor: TButton
Tag = 2
Left = 8
Top = 68
Width = 152
Height = 22
Caption = 'Falling Bar Colour'
TabOrder = 2
end
object btnEvColor: TButton
Tag = 3
Left = 8
Top = 92
Width = 152
Height = 22
Caption = 'Flat Bar Colour'
TabOrder = 3
end
end
object grpLayout: TGroupBox
Left = 4
Top = 567
Width = 172
Height = 92
Caption = 'Panel Layout'
TabOrder = 4
object lblKRatio: TLabel
Left = 8
Top = 18
Width = 67
Height = 14
Caption = 'K-Line: 50%'
end
object lblVRatio: TLabel
Left = 8
Top = 56
Width = 75
Height = 14
Caption = 'Volume: 25%'
end
object trkKRatio: TTrackBar
Left = 8
Top = 32
Width = 152
Height = 22
Max = 75
Min = 15
Position = 50
TabOrder = 0
TickStyle = tsNone
end
object trkVRatio: TTrackBar
Left = 8
Top = 70
Width = 152
Height = 22
Max = 50
Min = 10
Position = 25
TabOrder = 1
TickStyle = tsNone
end
end
object grpInfo: TGroupBox
Left = 4
Top = 665
Width = 172
Height = 108
Caption = 'Current Bar Info'
TabOrder = 5
object mmoInfo: TMemo
Left = 9
Top = 17
Width = 160
Height = 88
BorderStyle = bsNone
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Courier New'
Font.Style = []
ParentFont = False
ReadOnly = True
ScrollBars = ssVertical
TabOrder = 0
end
end
end
object pnlRight: TPanel
Left = 960
Top = 36
Width = 220
Height = 778
Align = alRight
BevelOuter = bvNone
TabOrder = 2
object grpList: TGroupBox
Left = 4
Top = 4
Width = 212
Height = 756
Caption = 'Available Stocks'
TabOrder = 0
object lstStocks: TListBox
Left = 4
Top = 18
Width = 200
Height = 730
ItemHeight = 14
TabOrder = 0
end
end
end
object Chart: TStockChart
Left = 186
Top = 36
Width = 774
Height = 778
Align = alClient
TabOrder = 3
TabStop = True
DataPath = '.\DATA\日K线'
KLineRatio = 0.500000000000000000
VolumeRatio = 0.250000000000000000
end
object ColorDlg: TColorDialog
Left = 548
Top = 6
end
end
其他文件¶
- Extractor_Icon.ico: 应用程序图标
- Project1.xml: 项目配置文件
- fDemo.pydfm: 窗体设计文件(二进制格式,由窗体设计器生成)
- DATA/日K线/: 包含13个.DAT格式的股票日K线数据文件
详细分析¶
功能概述¶
TStockChart股票图表查看器,支持加载和显示股票日K线数据。
使用的组件¶
- frmDemo (TfrmDemo)
- splitter (TSplitter)
- pnlTop (TPanel)
- lblStock (TLabel)
- lblStatus (TLabel)
- edtStock (TEdit)
- btnLoad (TButton)
- btnZoomIn (TButton)
- btnZoomOut (TButton)
- btnFirst (TButton)
- btnLeft (TButton)
- btnRight (TButton)
- btnLast (TButton)
- pnlLeft (TPanel)
- grpDisplay (TGroupBox)
- chkMA (TCheckBox)
- chkVMA (TCheckBox)
- chkDate (TCheckBox)
- chkDot (TCheckBox)
- chkHL (TCheckBox)
- chkRSI (TCheckBox)
- grpMA (TGroupBox)
- lblMA0 (TLabel)
- lblMA1 (TLabel)
- lblMA2 (TLabel)
- lblMA3 (TLabel)
- lblMA4 (TLabel)
- lblMA5 (TLabel)
- seMA0 (TSpinEdit)
- seMA1 (TSpinEdit)
- seMA2 (TSpinEdit)
- seMA3 (TSpinEdit)
- seMA4 (TSpinEdit)
- seMA5 (TSpinEdit)
- grpRSI (TGroupBox)
- lblRSI0 (TLabel)
- lblRSI1 (TLabel)
- seRSI0 (TSpinEdit)
- seRSI1 (TSpinEdit)
- grpColor (TGroupBox)
- btnBgColor (TButton)
- btnUpColor (TButton)
- btnDnColor (TButton)
- btnEvColor (TButton)
- grpLayout (TGroupBox)
- lblKRatio (TLabel)
- lblVRatio (TLabel)
- trkKRatio (TTrackBar)
- trkVRatio (TTrackBar)
- grpInfo (TGroupBox)
- mmoInfo (TMemo)
- pnlRight (TPanel)
- grpList (TGroupBox)
- lstStocks (TListBox)
- Chart (TStockChart)
- ColorDlg (TColorDialog)
技术特点¶
- 包含56个GUI组件
- 定义22个事件处理
- 使用TStockChart股票图表控件
- 支持K线显示、均线、RSI等技术指标
- 支持缩放、滚动、颜色自定义
窗体属性¶
- caption: TStockChart Demo
- height: 814
- width: 1180
代码分析¶
导入的模块: - import os - from glcl import *
定义的类: - frmDemo
定义的方法: - init - SyncControls - ScanStockList - btnLoadClick - btnZoomInClick - btnZoomOutClick - btnFirstClick - btnLastClick - btnLeftClick - btnRightClick - chkMAClick - chkVMAClick - chkDateClick - chkDotClick - chkHLClick - chkRSIClick - seMAChange - seRSIChange - btnColorClick - trkKRatioChange - trkVRatioChange - lstStocksClick - ChartDataIndexChange - ChartStockLoaded - ChartStockNotFound - UpdateInfoPanel
事件绑定: - self.Chart.OnDataIndexChange = self.ChartDataIndexChange - self.Chart.OnStockLoaded = self.ChartStockLoaded - self.Chart.OnStockNotFound = self.ChartStockNotFound - self.btnLoad.OnClick = self.btnLoadClick - self.btnZoomIn.OnClick = self.btnZoomInClick - self.btnZoomOut.OnClick = self.btnZoomOutClick - self.btnFirst.OnClick = self.btnFirstClick - self.btnLast.OnClick = self.btnLastClick - self.btnLeft.OnClick = self.btnLeftClick - self.btnRight.OnClick = self.btnRightClick - self.chkMA.OnClick = self.chkMAClick - self.chkVMA.OnClick = self.chkVMAClick - self.chkDate.OnClick = self.chkDateClick - self.chkDot.OnClick = self.chkDotClick - self.chkHL.OnClick = self.chkHLClick - self.chkRSI.OnClick = self.chkRSIClick - self.seMA0.OnChange = self.seMAChange - self.seMA1.OnChange = self.seMAChange - self.seMA2.OnChange = self.seMAChange - self.seMA3.OnChange = self.seMAChange - self.seMA4.OnChange = self.seMAChange - self.seMA5.OnChange = self.seMAChange - self.seRSI0.OnChange = self.seRSIChange - self.seRSI1.OnChange = self.seRSIChange - self.btnBgColor.OnClick = self.btnColorClick - self.btnUpColor.OnClick = self.btnColorClick - self.btnDnColor.OnClick = self.btnColorClick - self.btnEvColor.OnClick = self.btnColorClick - self.trkKRatio.OnChange = self.trkKRatioChange - self.trkVRatio.OnChange = self.trkVRatioChange - self.lstStocks.OnClick = self.lstStocksClick