当电力市场碰上量化分析技术,如何构建高效电力交易解决方案?

在数字化浪潮的推动下,物联网技术正重塑着各领域,电力交易市场亦不例外。作为能源市场的关键一环,电力交易的效率和透明度对于保障能源系统的稳定运行和可持续发展具有重要意义。物联网技术的兴起为电力交易市场带来了精细化资源管理的新机遇。物联网通过连接数以亿计的设备和传感器,收集和交换数据,为电力交易提供了前所未有的洞察力与自动化潜力。基于此,电力交易行情数据解决方案通过集成先进的数据分析工具和算法,对电力市场的供需变化、价格波动等关键信息进行深入挖掘和分析,帮助市场参与者制定更精准的交易决策,优化电力资源配置,同时提升市场响应速度和交易效率。

本文作为电力交易市场主体信息化的开篇之作,为大家介绍如何构建高效的电力交易行情数据存储与清洗的解决方案,助力市场参与者精准理解市场动态,提升决策质量与效率

1. 综述

1.1 电力交易简介

电力交易是指将电力作为一种商品,在电力市场中进行买卖的行为。在电力市场中,电力交易不仅包括电能量交易,还包括合同转让交易、发电权交易等。按照种类划分,电力交易可以分为中长期交易、现货交易和辅助服务交易等。

电力市场化交易通过优化资源配置,实现电力资源在时间和空间上的高效分配,从而提升电力系统的运行效率。此外,市场化交易还有助于构建公平竞争的市场环境,推动可再生能源的广泛应用。通过诸如绿色电力交易等机制,市场化交易促进了可再生能源的有效利用,为能源行业的绿色、低碳转型提供了有力支持。

目前,我国电力市场正在朝着更加市场化、绿色化和高效化的方向发展,已处于现货市场建设的关键环节。同时,市场主体多元化、交易范围扩大以及政策支持都是推动电力市场发展的重要因素。

1.2 电力交易中的量化交易技术

量化交易技术是一种运用数学模型和计算机算法来分析市场数据,实现交易策略自动化执行的先进交易方法。

电力交易中引入量化交易技术,能够提高交易效率、减少人为错误、快速响应市场变化、发现和利用套利机会以及执行复杂的交易策略。一套完整的量化交易大体上包含行情数据接入、数据清洗、数据存储、因子挖掘、因子相关性分析、策略回测、实盘和绩效归因等流程。

在量化交易中,行情数据是基石。电力行情包含了申报日期、标的日期、标的时段、最新价、成交量、成交均价、未成交量、未成交均价、买卖三档量价等丰富的数据,蕴藏了价格波动、市场走势和交易信号等信息。基于电力行情数据,交易员和策略研究员可以构建电力交易的量化因子,通过量化因子进行收益率预测、风险管理、投资组合构建、策略开发和市场分析等。

2. 电力交易行情数据管理面临的挑战

电力交易行情数据的管理面临以下挑战:

  • 行情数据清洗:参与电力交易的市场主体整体信息化水平处于初级阶段,数据清洗绝大多数都是人工进行的,每一天都需要手工进行一次行情数据清洗,耗费了大量的时间。
  • 行情数据存储:数据存储绝大多数都是基于 Excel。市场初期,通过 Excel 等简单工具可以勉力维持,但随着电力现货市场的常态化运行、交易流动性的持续增加以及跨省交易的不断发展,行情数据的量级会呈爆炸式增长,以 Excel 为载体便无法满足需求。
  • 实时行情数据接入:现阶段,由于法律法规和信息披露的要求,电力交易中心并未向市场主体开放实时行情数据的接入接口,市场主体无法像金融市场主体一样获取实时的行情数据,只能获取到历史数据。

因此,一套高效的数据清洗、数据存储解决方案,能够极大地提高研究员的效率,更加专注于因子和策略本身。

3. 构建高效的电力交易解决方案

电力交易市场的行情数据是一种带时间戳的结构化数据,从划分上来说,行情数据属于时序数据。引入数据库是行情数据管理信息化最优的解决方案。

DolphinDB 作为一款基于高性能时序数据库,支持复杂分析与流处理的实时计算平台,集成了功能强大的编程语言和高吞吐率的流数据分析系统,为海量结构化数据的快速存储、检索、分析及计算提供一站式解决方案。

上述电力交易行情数据在数据清洗与存储时面对的问题,可由 DolphinDB 在存储、分析和计算上支持的以下特性,以及基于这些特性的组合使用得以解决:

  • 强大的数据 ETL 工具:DolphinDB 内置1500+函数,提供了丰富的转换和清洗功能,支持数据格式化、缺失值填充、异常值处理、离散化处理、数据整合、数据过滤、聚合和排序等操作。这些功能使得电力行情数据清洗和转换变得简单而高效。
  • 高效存储方式:数据分区列式存储。针对电力行情数据可采用时间 + 标的日的方式组合分区来达成灵活分区存储,对于不同分区数据可以多线程并行操作。
  • 高效压缩算法:支持 lz4、delta 压缩算法,大大提升压缩率,节约硬件资源。
  • 高效排序算法:sortColumn 对分区内数据排序存储,快速定位数据在分区中的位置。

4. 存储方案设计

4.1 数据模型设计

数据模型与数据的写入、查询、更新、删除常见操作密切相关,合理的数据模型不仅能高效地表现数据中蕴藏的信息,还能极大地提升效率,在一定程度上节约硬件资源。因此,在实施整个解决方案之前,需先设计合理的数据模型。

以中长期连续运营交易为例,原始行情数据包含申报日期、标的日期、标的时段、最新价、成交量、成交均价、未成交量、未成交均价、买卖三档量价、持仓量等字段。如下表所示:

表1

字段名称数据类型描述
timeTIMESTAMP时间戳
dateDATE申报日期
tradeDateDATE标的日期
typeSYMBOL是否分时交易
symbolSYMBOL标的时段
lastPriceDOUBLE最新价
turnoverLONG成交量
turnoverPriceDOUBLE成交均价
turndownLONG未成交量
turndownPriceDOUBLE未成交均价
askPrice1DOUBLE买一档价
askPrice2DOUBLE买二档价
askPrice3DOUBLE买三档价
askVolume1DOUBLE买一档量
askVolume2DOUBLE买二档量
askVolume3DOUBLE买三档量
bidPrice1DOUBLE卖一档价
bidPrice2DOUBLE卖二档价
bidPrice3DOUBLE卖三档价
bidVolume1DOUBLE卖一档量
bidVolume2DOUBLE卖二档量
bidVolume3DOUBLE卖三档量

表1所示的行情数据在 DolphinDB 中有两种建模方案,第一种方案将买卖三档的量价分别用一个字段来表示,表结构如表1所示;第二种方案将买三档量、买三档价、卖三档量、卖三档价分别用一个字段来存储。

第二种建模方案的数据表结构如表2所示:

表2

字段名称数据类型描述
timeTIMESTAMP时间戳
dateDATE申报日期
tradeDateDATE标的日期
typeSYMBOL是否分时交易
symbolSYMBOL标的时段
lastPriceDOUBLE最新价
turnoverLONG成交量
turnoverPriceDOUBLE成交均价
turndownLONG未成交量
turndownPriceDOUBLE未成交均价
askPriceDOUBLE[]买三档价
askQytDOUBLE[]买三档量
bidPriceDOUBLE[]卖三档价
bidQytDOUBLE[]卖三档量

第二种建模方式引入了 DolphinDB 特有的数据存储结构:Array Vector。Array Vector 是 DolphinDB 针对包含多档位信息行情数据的特点研发的一种方便、灵活且高效的数据结构。

与第一种建模方案相比,第二种方案可以显著地简化某些常用的查询与计算代码,提高存储和计算性能。

4.2 分区方案设计

数据库分区是将一个大型的数据表分成多个小型子表的技术,每个子表称为一个分区,每个分区可以独立地进行管理和维护。在电力行情数据存储中,对于策略研究人员来说,分区技术能缩减数据的范围,提高查询性能。此外,分区还能提高系统的并发能力与可用性等。

那么,如何对电力行情数据进行分区呢?分区的主要目的之一是提高数据库在海量数据场景下的查询性能,只有了解行情数据的使用场景和方式,才能给出合理的分区方案。一般来说,进行数据分析与因子挖掘时,通常根据申报日期、标的日期、标的时段、交易类型等条件筛选数据。

因此,分区方案如下:从申报日和标的日两个维度来进行分区,竞价日选择按天进行值分区;标的日也选择按天进行值分区。

4.3 压缩算法设计

对数据进行压缩时,不仅要考虑压缩率,还要兼顾解压速度。DolphinDB 内置 lz4 和 delta 两种压缩算法,根据不同类型的数据采用合适的压缩算法能极大地提升压缩率,降低存储成本。

对于 SHORT, INT, LONG, DECIMAL, 时间或日期类型数据,采用 delta 算法压缩能提升压缩率的同时保证解压速度,其余类型的数据一般建议选择 lz4 算法。

4.4 建库建表

综上所述,连续运营行情数据的建库建表代码如下所示:

create database "dfs://snapshot1" partitioned by VALUE(2024.01.01..2024.01.10),VALUE(2024.01.01..2024.01.10),engine = "TSDB"
create table "dfs://snapshot1"."data"(
    time TIMESTAMP [comment = "当前时刻",compress = "delta"],
    date DATE [comment = "当前日期",compress = "delta"],
    tradeDate DATE [comment = "标的日",compress = "delta"],
    type SYMBOL [comment = "是否分时交易"],
    symbol SYMBOL [comment = "标的时段"],
    lastPrice DOUBLE [comment = "最新价"]
    turnover DOUBLE [comment = "成交量(含线损)"],
    turnoverPrice DOUBLE [comment = "成交均价"],
    turndown DOUBLE [comment = "未成交量(含线损)"],
    turndownPrice DOUBLE [comment = "未成交均价"],
    askPrice DOUBLE[] [comment = "买三档价格"],
    askQyt DOUBLE[] [comment = "买三档量"],
    bidPrice DOUBLE[] [comment = "卖三档价格"],
    bidQyt DOUBLE[] [comment = "卖三档量"]
)
partitioned by date,tradeDate,
sortColumns = ["type","symbol","time"],
keepDuplicates = ALL

5. 数据清洗与导入

电力交易中心交易平台中,连续运营交易多档行情数据界面如下图所示:

上图中包含了申报日、标的日和市场行情等信息。正常情况下,交易申报日(T日)为周一至周三时,连续运营日滚动交易标的为 T+3日至 T+5日每日24个时段的电量;交易申报日(T日)为周四至周五时,连续运营日滚动交易标的为 T+3日至T+6日每日24个时段的电量。上图中,申报日为3月5日,标的日为3月8日、3月9日,3月10日。数据中没有申报日、标的日、交易类型等字段。因此在入库时,需要进行清洗,将这些字段补全。此外,还需要将买卖三档的量价数据组织成 ArrayVector 形式。

导入脚本详见附录。在脚本中,定义了importData函数。importData接收一个字符串参数agrs,用于指定导入行情数据文件的存放路径。importData函数将行情数据csv文件导入成 DolphinDB 内存表,经过一系列的数据清洗,最终转换成标准的行情数据,并落库存储。其实现步骤如下:

  • 将 csv 文件数据加载到 DolphinDB 内存表
  • 数据清洗,处理行情数据的量和价
  • 增加申报日、标的日两个字段

行情数据导入后,在 DolphinDB 中查看数据如下图所示:

行情数据导入后,基于行情数据,可以计算一些简单的因子,如买方最高价/最低价,卖方最高价/最低价,买方市场总量,卖方市场总量等因子。如下图所示:

6. 展望

本文是电力交易市场主体信息化的开篇之作。后续,我们计划逐步发布一系列深入文章和教程,涵盖如何基于 DolphinDB 挖掘电力交易因子、进行因子管理、因子相关性分析,以及如何基于 DolphinDB 进行电力交易策略开发和回测等。随着电力交易市场信息化进程的持续推进和市场法规的逐步完善,我们还将探讨如何利用 DolphinDB 接入实时市场数据,以提高整个交易流程的效率和流畅性,实现市场主体信息化的全面贯通,从而打通信息化建设的“最后一公里”。

附录:数据清洗导入脚本

def importData(filePath){
//filePath:文件路径
    schema = extractTextSchema(filePath)
    totalNum = schema.size()
    if(totalNum==13){
        schema["type"] = `STRING`DOUBLE`STRING join take(`DOUBLE,10)
    }else{
        schema["type"] = `STRING`DOUBLE`STRING join take(`DOUBLE,totalNum-3)
    }
    t = loadText(filePath,,schema)
    update t set col2 = "查看"

    //行号为奇数的是量,偶数的是价
    data = select *,rowNo(col3)+1 as RN from t[,3:11]
    //前8行为量,后8行为价
    tmp = table(matrix(select * from data where RN%2 = 1) join matrix( select * from data where RN%2 = 0))
    dropColumns!(tmp,`col8`col17)
    askAndBid = select col0 as 成交量含线损,col9 as 成交均价含线损,col1 as 未成交量含线损,col10 as 未成交均价含线损,
                        fixedLengthArrayVector(col2,col3,col4) as 买三档量,
                        fixedLengthArrayVector(col5,col6,col7) as 卖三档量,
                        fixedLengthArrayVector(col11,col12,col13) as 买三档价格,
                        fixedLengthArrayVector(col14,col15,col16) as 卖三档价格
                from tmp
    
    //行号为奇数的是一条
    tmp1 = select *,rowNo(col0)+1 as RN from t
    tmp2 = select col0 as 交易时段,col1 as 最新价,col2 as 趋势,col11 as 持有量,col12 as 未成交量 from tmp1 where RN%2 = 1
    tmp3 = tmp2 join askAndBid


    //为数据打上当前日期,交易日期,是否为分时用户
    Date = temporalParse(left(right(filePath,12),8),"yyyyMMdd")

    //确定连续滚动的日期范围
    if(Date in 2024.04.01..2024.04.03){
        tradeDates = Date + (3..7)
    }else if( Date in 2024.04.28..2024.04.30){
        tradeDates = Date + (3..9)
    }else if(Date == 2024.04.07){
        tradeDates = Date + (3..5)
    }else if(weekday(Date) in (1,2,3)){
        tradeDates = Date + (3..5)
    }else{
        tradeDates = Date + (3..6)
    }
    DateList = take(Date,tmp3.size())
    tradeDateList = stretch(tradeDates,tradeDates.size()*48)
    isTime = take(stretch(`分时`非分时,48),tradeDates.size()*48)
    res = table(DateList as 当前日期,tradeDateList as 交易日期,isTime as 是否分时) join tmp3
    newColumn = `当前日期`交易日期`是否分时`交易时段`最新价`成交量含线损`成交均价含线损`未成交量含线损`未成交均价含线损`买三档价格`卖三档价格`买三档量`卖三档量`持有量`未成交量`趋势
    res.reorderColumns!(newColumn)

    res = select 
            take(2024.04.07T10:00:09.000,res.size()) as time,
            当前日期 as date,
            交易日期 as tradeDate,
            是否分时 as type,
            交易时段 as symbol,
            最新价 as lastPrice,
            成交量含线损 as turnOver,
            成交均价含线损 as turnOverPrice,
            未成交量含线损	as turnDown,
            未成交均价含线损 as tunrnDownPrice,
            买三档价格 as askPrice,
            卖三档价格	 as bidPrice,
            买三档量 as askQyt,
            卖三档量 as bidQyt
          from res
    pt1 = loadTable("dfs://snapshot","data")
    pt1.append!(res)
}

//文件路径
filePath = "./20240407.csv"
importData(filePath)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/748358.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面向遥感图像的多阶段特征融合目标检测方法

源自:电子学报 作者:陈立 张帆 郭威 黄赟 注:若出现无法显示完全的情况,可 V 搜索“人工智能技术与咨询”查看完整文章 摘 要 遥感图像目标具有多尺度、大横纵比、多角度等特性,给传统的目标检测方法带来了新的…

单片机是否有损坏,怎沫判断

目录 1、操作步骤: 2、单片机损坏常见原因: 3、 单片机不工作的原因: 参考:细讲寄存器读写与Bit位操作原理--单片机C语言编程Bit位的与或非屏蔽运算--洋桃电子大百科P019_哔哩哔哩_bilibili 1、操作步骤: 首先需要…

煤安防爆手机为什么能在煤矿井下使用

煤安防爆手机之所以能在煤矿井下使用,是因为它们经过特殊设计,符合严格的防爆安全标准,能够防止电火花引发爆炸,同时具备防尘防水、抗冲击等特性,确保在恶劣的煤矿环境中稳定可靠地运行,为工作人员提供安全…

新交友盲盒+付费进群二合一源码+视频教程

盲盒交友脱单系统 包括项目前端和后端的讲解、宝塔面板的安装教程,以及盲盒交友和付费进群二合一的搭建教程。无论你是技术小白还是有一定技术基础,都能轻松搭建出属于自己的盲盒交友平台。

[leetcode]first-unique-character-in-a-string 字符串中的第一个唯一字符

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int firstUniqChar(string s) {unordered_map<int, int> frequency;for (char ch: s) {frequency[ch];}for (int i 0; i < s.size(); i) {if (frequency[s[i]] 1) {return i;}}return -1;} };

DP:二维费用背包问题+似包非包

二维费用的背包问题&#xff1a;大多以01背包为基础&#xff0c;存在两个限制条件&#xff01; 一、一和零 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public: //需要满足两个条件的我们称之为二位费用的背包问题int findMaxForm(vector<string>&…

WEB与低代码:B/S架构在开发中的应用与优势

在互联网迅猛发展的今天&#xff0c;WEB应用已经成为人们日常生活和工作中不可或缺的一部分。随着技术的进步和需求的多样化&#xff0c;开发高效、灵活且易于维护的WEB应用变得尤为重要。B/S架构&#xff08;Browser/Server Architecture&#xff09;作为一种常见的WEB应用架构…

AI+病理组学,预测高级别浆液性卵巢癌(HGSOC)患者对铂基化疗的反应|文献精析·24-06-27

小罗碎碎念 小罗推荐 选这篇文献进行精析的原因比较直接——前两天组会提到了&#xff0c;这是我组会准备的PPT&#xff0c;正好让大家快速的了解一下这篇文章。 文献简介 这篇文章是关于一种新型的基于组织病理学图像的深度学习分类器——Pathologic Risk Classifier for High…

Linux驱动开发-02字符设备驱动开发初步

一、驱动开发的前期准备 在进入驱动开发之前&#xff0c;需要烧写UBoot、内核、设备树&#xff0c;做一些前期的准备工作&#xff0c;确保我们开发板上的内核版本和Ubuntu上是一致的才能进行正式开发 1.U-Boot 2.内核版本 3.使用TFTP挂载的内核和设备树 二、Linux驱动开发与裸机…

合约期VS优惠期,搞明白他们的区别才能避免很多坑!

在购买流量卡时&#xff0c;相信大家也都发现了&#xff0c;市面上的不少套餐都是有合约期和优惠期的&#xff0c;尤其是联通和移动&#xff0c;那么&#xff0c;什么是合约期&#xff1f;什么又是优惠期呢&#xff1f; ​ 其实&#xff0c;目前很多在网上办理的大流量卡都是有…

matlab量子纠缠态以及量子门操作下的量子态

前言 今天我们来聊聊题外话&#xff0c;量子纠缠&#xff0c;在目前物理分支中&#xff0c;要说最深&#xff0c;最能改变人类对宇宙影响的莫过于量子力学了&#xff0c;假如我们可以人为的对两个粒子施加纠缠态&#xff0c;那么我们将可以足不出户的完成对外界的操控 简介 …

Arm Linux 修改 网络 mac 地址的方式方法

一、指令修改 查看网络信息指令 ifconfig修改网络 mac 地址&#xff0c;指令 ifconfig 网卡名 hw ether mac地址例如&#xff1a; ifconfig eth0 hw ether 08:00:27:00:01:96二、C语言程序修改 1.使用 ioctl 和 SIOCSIFHWADDR 来设置MAC地址&#xff0c;示例代码如下&…

空间转录组学联合单细胞转录组学揭示卵巢癌生存相关受配体对

卵巢癌&#xff0c;作为女性生殖系统中的一种常见恶性肿瘤&#xff0c;其高级别浆液性卵巢癌&#xff08;HGSC&#xff09;亚型尤其致命。尽管多数患者对初次治疗反应良好&#xff0c;但超过75%的晚期HGSC患者会在治疗后复发&#xff0c;并且对化疗药物产生耐药性。然而&#x…

信息系统项目管理师(项目管理师)

项目管理者再坚持“聚焦于价值”原则时&#xff0c;应该关注的关键点包括&#xff1a;1价值是项目成功的最终指标&#xff1b;2价值可以再整个项目进行期间、项目结束或完成后实现&#xff1b;3价值可以从定性和/或定量的角度进行定义和衡量&#xff1b;4以成果为导向&#xff…

【前端】实现时钟网页

【前端】实现时钟网页 文章目录 【前端】实现时钟网页项目介绍代码效果图 项目介绍 时钟显示在网页中央&#xff0c;并且使网页能够切换白天和夜晚两种模式。搭建基本的html结构&#xff0c;动态得到实时的时&#xff0c;分&#xff0c;秒 通过Date()函数获得。将得到的数字根…

手机定位技术全解析:原理、发展与应用

1. 引言 背景介绍 最近&#xff0c;神仙姐姐刘亦菲主演的电视剧《玫瑰的故事》中的一段情节引发了广泛讨论。剧中&#xff0c;方协文&#xff08;丈夫&#xff09;对玫瑰&#xff08;妻子&#xff09;的控制欲变本加厉&#xff0c;竟然偷偷在她的手机上安装监控软件&#xff…

考研数学(4/9):微分方程

微分方程 微分方程是高等数学中一个重要的分支&#xff0c;也是考研数学数一中必考的内容。本章主要介绍微分方程的概念、一阶微分方程、高阶线性微分方程以及微分方程的应用。 1. 微分方程的概念 1.1 微分方程的定义 微分方程 是指包含未知函数及其导数的方程。 更准确地说&am…

宠物领养救助管理系带万字文档java项目基于springboot+vue的宠物管理系统java课程设计java毕业设计

文章目录 宠物领养救助管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档&#xff08;9.9&#xffe5;带走&#xff09; 宠物领养救助管理系统 一、项目演示 宠物领养救助系统 二、项目介绍 基于springbootv…

Linux基础 - iptables 与 firewalld 防火墙

目录 零. 简介 一. iptables 二. firewalld 三. 总结 零. 简介 iptables iptables 是 Linux 内核中集成的一种基于命令行的防火墙工具。它通过一系列规则来控制网络数据包的流动&#xff0c;包括允许、拒绝、修改数据包等操作。iptables 可以对入站、出站和转发的数据包进…

数据驭王: PostgreSQL教程指南解密

PostgreSQL教程大纲 一、介绍1.1 什么是PostgreSQL&#xff1f;1.2 PostgreSQL的历史和发展1.3 为什么选择PostgreSQL&#xff1f; 二、安装和设置2.1 下载和安装PostgreSQL2.2 配置PostgreSQL2.3 测试PostgreSQL 三、基本操作3.1 连接到PostgreSQL数据库步骤一&#xff1a;安装…