【python量化交易】—— Alpha选股策略 - Qteasy自定义交易策略【附源码】
使用qteasy创建并回测Alpha选股交易策略
- 使用`qteasy`创建并回测Alpha选股交易策略
- 策略思想
- 第一种自定义策略设置方法,使用持仓数据和选股数据直接生成比例交易信号PS信号:
- 第二种自定义策略设置方法,使用`PT`交易信号设置持仓目标:
- 第三种自定义策略设置方法:
使用qteasy
创建并回测Alpha选股交易策略
我们今天使用qteasy
来回测一个alpha选股交易策略,qteasy
是一个功能全面且易用的量化交易策略框架,Github地址在这里。使用它,能轻松地获取历史数据,创建交易策略并完成回测和优化,还能实盘运行。项目文档在这里。
为了继续本章的内容,您需要安装qteasy【教程1】,并下载历史数据到本地【教程2、),详情可以参考更多教程【教程3】。
建议您先按照前面教程的内容了解qteasy
的使用方法,然后再参考这里的例子创建自己的交易策略。
策略思想
本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票,随后平掉排名EV/EBITDA不在最小的30的股票持仓并等权购买EV/EBITDA最小排名在前30的股票
回测数据为:SHSE.000300沪深300指数成份股
回测时间为:2016-04-05 到 2021-02-01
import qteasy as qt
import pandas as pdd
import numpy as np
在选股之前,需要检查需要的历史数据
EV/EBITDA数据并不直接存在于qteasy定义的数据类型中,需要通过几个数据组合计算出来
EV/EBITDA = (Market Capitalization + Total Debt - Total Cash) / EBITDA
上面几个数据分别代表总市值、总负债、总现金及现金等价物,这些数据需要从qteasy
内置的数据类型中分别提取,并使用上面的公式计算后,作为选股因子。排除掉小于0的因子后,将所有选股因子从小到大排列,选出因子排在最前的30支股票,将手中的全部资金平均分配投入到所有选中的股票中持有一个月,直到下一次选股为止。
我们可以通过下面的方法检查数据检查结果。
htypes = 'total_mv, total_liab, c_cash_equ_end_period, ebitda'
shares = qt.filter_stock_codes(index='000300.SH', date='20220131')
print(shares[0:10])
dt = qt.get_history_data(htypes, shares=shares, asset_type='any', freq='m')one_share = shares[24]df = dt[one_share]df['ev_to_ebitda'] = (df.total_mv + df.total_liab - df.c_cash_equ_end_period) / df.ebitda
输出结果如下
['000001.SZ', '000002.SZ', '000063.SZ', '000066.SZ', '000069.SZ', '000100.SZ', '000157.SZ', '000166.SZ', '000301.SZ', '000333.SZ']
有了上面的数据定义,我们就可以创建这样的选股策略了。
实际上,我们可以使用好几种不同的方法实现同样的选股策略:
第一种自定义策略设置方法,使用持仓数据和选股数据直接生成比例交易信号PS信号:
使用GeneralStrategy
策略类,计算选股因子后,去掉所有小于零的因子,排序后提取排名前三十的股票
按以下逻辑生成交易信号:
1,检查当前持仓,如果持仓的股票不在选中的30个中间,则全数卖出
2,检查当前持仓,如果新选中的股票没有持仓,则等权买入新增选中的股票
设置交易信号类型为PS
,生成交易信号
由于生成交易信号需要用到持仓数据,因此不能使用批量生成模式,只能使用stepwise
模式
策略的定义如下
class AlphaPS(qt.GeneralStg):def realize(self, h, r=None, t=None, pars=None):# 从历史数据编码中读取四种历史数据的最新数值total_mv = h[:, -1, 0] # 总市值total_liab = h[:, -1, 1] # 总负债cash_equ = h[:, -1, 2] # 现金及现金等价物总额ebitda = h[:, -1, 3] # ebitda,息税折旧摊销前利润# 从持仓数据中读取当前的持仓数量,并找到持仓股序号own_amounts = t[:, 0]owned = np.where(own_amounts > 0)[0] # 所有持仓股的序号not_owned = np.where(own_amounts == 0)[0] # 所有未持仓的股票序号# 选股因子为EV/EBIDTA,使用下面公式计算factors = (total_mv + total_liab - cash_equ) / ebitda# 处理交易信号,将所有小于0的因子变为NaNfactors = np.where(factors < 0, np.nan, factors)# 选出数值最小的30个股票的序号arg_partitioned = factors.argpartition(30)selected = arg_partitioned[:30] # 被选中的30个股票的序号not_selected = arg_partitioned[30:] # 未被选中的其他股票的序号(包括因子为NaN的股票)# 开始生成交易信号signal = np.zeros_like(factors)# 如果持仓为正,且未被选中,生成全仓卖出交易信号own_but_not_selected = np.intersect1d(owned, not_selected)signal[own_but_not_selected] = -1 # 在PS信号模式下 -1 代表全仓卖出# 如果持仓为零,且被选中,生成全仓买入交易信号selected_but_not_own = np.intersect1d(not_owned, selected)signal[selected_but_not_own] = 0.0333 # 在PS信号模式下,+1 代表全仓买进 (如果多只股票均同时全仓买进,则会根据资金总量平均分配资金)return signal
创建一个Operator
对象,并运行这个策略。
由于策略使用了当前持仓数据,因此只能使用stepwise
模式回测
alpha = AlphaPS(pars=(),par_count=0,par_types=[],par_range=[],name='AlphaPS',description='本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票',data_types='total_mv, total_liab, c_cash_equ_end_period, ebitda',strategy_run_freq='m',data_freq='d',window_length=100)
op = qt.Operator(alpha, signal_type='PS')
op.op_type = 'stepwise'
op.run(mode=1,asset_type='E',asset_pool=shares,trade_batch_size=100,sell_batch_size=1,trade_log=True)
输出结果如下:
====================================| || BACK TESTING RESULT || |====================================qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 0.0ms
time consumption for operation back looping: 6s 192.6msinvestment starts on 2016-04-05 00:00:00
ends on 2021-02-01 00:00:00
Total looped periods: 4.8 years.-------------operation summary:------------
Only non-empty shares are displayed, call
"loop_result["oper_count"]" for complete operation summarySell Cnt Buy Cnt Total Long pct Short pct Empty pct
000301.SZ 1 1 2 10.3% 0.0% 89.7%
000786.SZ 2 2 4 27.5% 0.0% 72.5%
000895.SZ 1 2 3 66.4% 0.0% 33.6%
002001.SZ 2 2 4 56.9% 0.0% 43.1%
002007.SZ 0 1 1 68.3% 0.0% 31.7%
002027.SZ 2 2 4 41.3% 0.0% 58.7%
002032.SZ 2 2 4 6.9% 0.0% 93.1%
002044.SZ 1 1 2 1.8% 0.0% 98.2%
002049.SZ 1 1 2 5.1% 0.0% 94.9%
002050.SZ 4 4 8 13.8% 0.0% 86.2%
... ... ... ... ... ... ...
603806.SH 3 3 6 62.1% 0.0% 37.9%
603899.SH 3 3 6 38.1% 0.0% 61.9%
000408.SZ 2 3 5 35.5% 0.0% 64.5%
002648.SZ 1 1 2 5.2% 0.0% 94.8%
002920.SZ 1 1 2 5.1% 0.0% 94.9%
300223.SZ 1 1 2 5.2% 0.0% 94.8%
300496.SZ 1 1 2 10.5% 0.0% 89.5%
600219.SH 0 1 1 6.1% 0.0% 93.9%
603185.SH 1 1 2 5.2% 0.0% 94.8%
688005.SH 1 1 2 3.5% 0.0% 96.5% Total operation fee: ¥ 750.28
total investment amount: ¥ 100,000.00
final value: ¥ 182,142.87
Total return: 82.14%
Avg Yearly return: 13.22%
Skewness: -0.36
Kurtosis: 2.40
Benchmark return: 65.96%
Benchmark Yearly return: 11.06%------strategy loop_results indicators------
alpha: 0.035
Beta: 1.175
Sharp ratio: 1.244
Info ratio: 0.005
250 day volatility: 0.113
Max drawdown: 19.03% peak / valley: 2018-05-22 / 2019-01-03recovered on: 2019-04-01===========END OF REPORT=============
第二种自定义策略设置方法,使用PT
交易信号设置持仓目标:
在完成选股因子的计算之后,直接设置每个股票的持仓目标,这样就不需要使用知道持仓数据,直接输出持仓目标信号
,在回测过程中根据实际持仓量生成交易信号。
class AlphaPT(qt.GeneralStg):def realize(self, h, r=None, t=None, pars=None):# 从历史数据编码中读取四种历史数据的最新数值total_mv = h[:, -1, 0] # 总市值total_liab = h[:, -1, 1] # 总负债cash_equ = h[:, -1, 2] # 现金及现金等价物总额ebitda = h[:, -1, 3] # ebitda,息税折旧摊销前利润# 选股因子为EV/EBIDTA,使用下面公式计算factors = (total_mv + total_liab - cash_equ) / ebitda# 处理交易信号,将所有小于0的因子变为NaNfactors = np.where(factors < 0, np.nan, factors)# 选出数值最小的30个股票的序号arg_partitioned = factors.argpartition(30)selected = arg_partitioned[:30] # 被选中的30个股票的序号not_selected = arg_partitioned[30:] # 未被选中的其他股票的序号(包括因子为NaN的股票)# 开始生成PT交易信号signal = np.zeros_like(factors)# 所有被选中的股票的持仓目标被设置为0.03,表示持有3.3%signal[selected] = 0.0333# 其余未选中的所有股票持仓目标在PT信号模式下被设置为0,代表目标仓位为0signal[not_selected] = 0 return signal
生成一个Operator对象,运行回测
alpha = AlphaPT(pars=(),par_count=0,par_types=[],par_range=[],name='AlphaSel',description='本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票',data_types='total_mv, total_liab, c_cash_equ_end_period, ebitda',strategy_run_freq='m',data_freq='d',window_length=100)
op = qt.Operator(alpha, signal_type='PT')
res = op.run(mode=1,asset_type='E',asset_pool=shares,PT_buy_threshold=0.00, # 如果设置PBT=0.00,PST=0.03,最终收益会达到30万元PT_sell_threshold=0.00,trade_batch_size=100,sell_batch_size=1,maximize_cash_usage=True,trade_log=True)
回测结果如下:
====================================| || BACK TESTING RESULT || |====================================qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 7.2ms
time consumption for operation back looping: 6s 308.5msinvestment starts on 2016-04-05 00:00:00
ends on 2021-02-01 00:00:00
Total looped periods: 4.8 years.-------------operation summary:------------
Only non-empty shares are displayed, call
"loop_result["oper_count"]" for complete operation summarySell Cnt Buy Cnt Total Long pct Short pct Empty pct
000301.SZ 1 1 2 10.3% 0.0% 89.7%
000786.SZ 2 3 5 27.5% 0.0% 72.5%
000895.SZ 1 1 2 68.7% 0.0% 31.3%
002001.SZ 2 2 4 57.5% 0.0% 42.5%
002007.SZ 0 1 1 68.3% 0.0% 31.7%
002027.SZ 6 7 13 41.3% 0.0% 58.7%
002032.SZ 3 1 4 7.5% 0.0% 92.5%
002044.SZ 1 1 2 1.8% 0.0% 98.2%
002049.SZ 1 1 2 5.1% 0.0% 94.9%
002050.SZ 4 4 8 13.8% 0.0% 86.2%
... ... ... ... ... ... ...
603806.SH 5 3 8 62.1% 0.0% 37.9%
603899.SH 2 3 5 36.3% 0.0% 63.7%
000408.SZ 3 5 8 35.5% 0.0% 64.5%
002648.SZ 1 1 2 5.2% 0.0% 94.8%
002920.SZ 1 1 2 5.1% 0.0% 94.9%
300223.SZ 1 2 3 5.2% 0.0% 94.8%
300496.SZ 1 1 2 10.5% 0.0% 89.5%
600219.SH 1 1 2 6.1% 0.0% 93.9%
603185.SH 1 1 2 5.2% 0.0% 94.8%
688005.SH 1 2 3 5.2% 0.0% 94.8% Total operation fee: ¥ 985.25
total investment amount: ¥ 100,000.00
final value: ¥ 189,723.44
Total return: 89.72%
Avg Yearly return: 14.18%
Skewness: -0.41
Kurtosis: 2.87
Benchmark return: 65.96%
Benchmark Yearly return: 11.06%------strategy loop_results indicators------
alpha: 0.044
Beta: 1.134
Sharp ratio: 1.284
Info ratio: 0.011
250 day volatility: 0.120
Max drawdown: 20.95% peak / valley: 2018-05-22 / 2019-01-03recovered on: 2019-09-09===========END OF REPORT=============
第三种自定义策略设置方法:
使用FactorSorter策略类,直接生成交易策略的选股因子,再根据
FactorSorter策略的选股参数实现选股,本质上与第二种方式相同,但是
可以大大减少代码量
设置交易信号类型为PT,生成持仓目标,自动生成交易信号
class AlphaFac(qt.FactorSorter): # 注意这里使用FactorSorter策略类def realize(self, h, r=None, t=None, pars=None):# 从历史数据编码中读取四种历史数据的最新数值total_mv = h[:, -1, 0] # 总市值total_liab = h[:, -1, 1] # 总负债cash_equ = h[:, -1, 2] # 现金及现金等价物总额ebitda = h[:, -1, 3] # ebitda,息税折旧摊销前利润# 选股因子为EV/EBIDTA,使用下面公式计算factor = (total_mv + total_liab - cash_equ) / ebitda# 对比第二种策略定义方法,使用FactorSorter策略类可以直接处理选股因子# 从而大大降低代码量# 由于使用因子排序选股策略,因此直接返回选股因子即可,策略会自动根据设置条件选股return factor
同样创建一个Operator对象,回测交易策略
注意这个交易策略需要更多的参数用于因子选股:
max_sel_count=30
设置选股数量,最多选出30个股票condition='greater'
设置筛选条件,仅筛选因子大于ubound的股票ubound=0.0
设置筛选条件,仅筛选因子大于0的股票weighting='even'
设置股票权重,所有选中的股票平均分配权重sort_ascending=True
设置排序方式,因子从小到大排序选择头30名
alpha = AlphaFac(pars=(),par_count=0,par_types=[],par_range=[],name='AlphaSel',description='本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票',data_types='total_mv, total_liab, c_cash_equ_end_period, ebitda',strategy_run_freq='m',data_freq='d',window_length=100,max_sel_count=30, # 设置选股数量,最多选出30个股票condition='greater', # 设置筛选条件,仅筛选因子大于ubound的股票ubound=0.0, # 设置筛选条件,仅筛选因子大于0的股票weighting='even', # 设置股票权重,所有选中的股票平均分配权重sort_ascending=True) # 设置排序方式,因子从小到大排序选择头30名
op = qt.Operator(alpha, signal_type='PT')
res = op.run(mode=1,asset_type='E',asset_pool=shares,PT_buy_threshold=0.0,PT_sell_threshold=0.0,trade_batch_size=100,sell_batch_size=1)
回测结果如下:
====================================| || BACK TESTING RESULT || |====================================qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 9.4ms
time consumption for operation back looping: 5s 831.0msinvestment starts on 2016-04-05 00:00:00
ends on 2021-02-01 00:00:00
Total looped periods: 4.8 years.-------------operation summary:------------
Only non-empty shares are displayed, call
"loop_result["oper_count"]" for complete operation summarySell Cnt Buy Cnt Total Long pct Short pct Empty pct
000301.SZ 1 2 3 10.3% 0.0% 89.7%
000786.SZ 2 3 5 27.5% 0.0% 72.5%
000895.SZ 1 0 1 62.6% 0.0% 37.4%
002001.SZ 2 2 4 55.8% 0.0% 44.2%
002007.SZ 3 1 4 68.3% 0.0% 31.7%
002027.SZ 2 9 11 41.3% 0.0% 58.7%
002032.SZ 2 0 2 5.9% 0.0% 94.1%
002044.SZ 1 1 2 1.8% 0.0% 98.2%
002049.SZ 1 1 2 5.1% 0.0% 94.9%
002050.SZ 4 5 9 13.8% 0.0% 86.2%
... ... ... ... ... ... ...
603517.SH 1 1 2 1.8% 0.0% 98.2%
603806.SH 6 3 9 39.8% 0.0% 60.2%
603899.SH 1 1 2 31.0% 0.0% 69.0%
000408.SZ 3 6 9 35.5% 0.0% 64.5%
002648.SZ 1 1 2 5.2% 0.0% 94.8%
002920.SZ 1 1 2 1.7% 0.0% 98.3%
300223.SZ 1 1 2 5.2% 0.0% 94.8%
600219.SH 1 1 2 6.1% 0.0% 93.9%
603185.SH 1 1 2 5.2% 0.0% 94.8%
688005.SH 1 1 2 5.2% 0.0% 94.8% Total operation fee: ¥ 928.22
total investment amount: ¥ 100,000.00
final value: ¥ 159,072.14
Total return: 59.07%
Avg Yearly return: 10.09%
Skewness: -0.28
Kurtosis: 3.29
Benchmark return: 65.96%
Benchmark Yearly return: 11.06%------strategy loop_results indicators------
alpha: -0.012
Beta: 1.310
Sharp ratio: 1.191
Info ratio: -0.010
250 day volatility: 0.105
Max drawdown: 20.49% peak / valley: 2018-05-22 / 2019-01-03recovered on: 2019-12-26===========END OF REPORT=============
相关文章:

【python量化交易】—— Alpha选股策略 - Qteasy自定义交易策略【附源码】
使用qteasy创建并回测Alpha选股交易策略 使用qteasy创建并回测Alpha选股交易策略策略思想第一种自定义策略设置方法,使用持仓数据和选股数据直接生成比例交易信号PS信号:第二种自定义策略设置方法,使用PT交易信号设置持仓目标:第三…...

简单记录下:Navicat 导出表结构至 Excel
首先我们需要通过sql语句查询出相关的表结构的结构 SELECT COLUMN_NAME AS 字段名称,COLUMN_TYPE AS 字段类型,IF(IS_NULLABLENO,否,是) AS 是否必填,COLUMN_COMMENT AS 注释FROM INFORMATION_SCHEMA.COLUMNSWHERE table_schema bs-gdsAND table_name sys_menu;查询的结构如下…...

黑马基于Web-socket的java聊天室基本解析
要是用Web-socket协议,我们要前端upgrade升级成web-socket协议 首先我们要引入springboot的websocket起步依赖,这样子方便使用,自己指定版本注意 <dependency><groupId>org.springframework.boot</groupId><artifactId&…...

【操作系统期末速成】内存管理|内存的装入模块在装入内存的方式|分配管理方式|页面置换算法|页面置换
🎥 个人主页:深鱼~🔥收录专栏:操作系统🌄欢迎 👍点赞✍评论⭐收藏 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到…...

图和网络笔记
文章目录 1. A X 0 AX0 AX02. A T Y 0 A^TY0 ATY03. A X 0 AX0 AX0和 A T Y 0 A^TY0 ATY0的关系 1. A X 0 AX0 AX0 一个图可以由节点和边组成,假设我们有一个节点notes :n4,边edges:m5的有向图,表示如下 通过以上电路…...

请求外部系统报错
报错信息: nested exception is com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: com.google.common.net.HostAndPort.getHostText()Ljava/lang/String; 在网上看了好几篇文章,和我的都不符合。 后面自己发现是我的系…...

电路板维修【四】
【开关电源输出电压偏低不稳,用示波器立马锁定故障范围】:https://www.bilibili.com/video/BV1pf421D73K?vd_source3cc3c07b09206097d0d8b0aefdf07958 可以用示波器查看MOS的输出波形来查看其是否损坏: 电源芯片的供电电压来回跳变…...

(程序设计语言)传值、传引用
1、传值(传递值): 在传值的情况下,函数接收到的是参数的一个副本,而不是参数本身。这意味着函数内部对参数的修改不会影响到原始值。传值通常用于基本数据类型(如整数、浮点数、布尔值等)的传递…...

一次基类类型对象无法被传递问题的分析
看下面一段代码: // proj2.cpp #include <iostream> using namespace std; class CharShape { public:CharShape(char ch) : _ch(ch) {};virtual void Show() 0; protected:char _ch; // 组成图形的字符 }; class Triangle : public CharShape { public:Tr…...

windows设置Redis服务后台自启动
问题 在日常开发过程中,redis是我们常用的缓存工具,但是由于redis对于Linux系统进行开发的,在Linux系统里可以通过修改redis.conf从而从而实现后台启动。 daemonize no 改成 daemonize yes 但是在window上如何也进行后台运行呢,…...

掌握Linux常用命令,扫平面试需求障碍
cd 切换目录。 > cd ../ #切换到父级目录 > cd /tmp # 切换到/tmp目录 > cd ~ # 切换到当前用户的家目录 ls命令 查看文件与目录的命令,list 的缩写。 > ls -l #列出长数据串,包含文件的属性与权限数据等 > ls -a #列出隐藏…...

c语言之文件打开模式
在c语言中,文件打开模式如下 r读模式: 允许对文件读取信息。若文件不存在,则会报错 w写模式: 允许向文件写入信息,若文件不存在,则创建一个文件 #include<stdio.h>int main() {FILE *fp;int i;char ay;fpfo…...

与禹老师学前端vue3学习汇总
24.5.15: 创建Vue3工程 1.确定自己电脑有没有nodejs环境,在cmd中输入node,如果出现Node.js的版本号说明已经有这个环境了,否则搜索Node.js安装 2.先在D盘创建一个文件夹Vue3_Study,然后在这个空文件夹中右键选择终端…...

Linux网络编程——HTTP协议的理解与运用
目录 前言 一、认识URL 二、认识HTTP样例 三、HTTP的报头内容 1.url 2. Content-Type 3.Method 方法 1.GET方法 2.POST方法 4、状态码 5.cookie和session 前言 我们知道,协议就是一种约定,客户端与服务端统一的用这种约定进行传输数据。我们…...

RestTemplate接口请求发送json、form数据格式以及处理接口错误状态码400 null
在使用RestTemplate发送HTTP请求时,你可以通过不同的方式发送JSON或表单数据(application/x-www-form-urlencoded)。同时,处理接口错误状态码(如400)和返回null的情况也是很重要的。以下是一些示例代码&…...

《Python编程从入门到实践》day29
# 昨日知识点回顾 修改折线图文字和线条粗细 矫正图形 使用内置格式 # 今日知识点学习 15.2.4 使用scatter()绘制散点图并设置样式 import matplotlib.pyplot as plt import matplotlib matplotlib.use(TkAgg)plt.style.use(seaborn-v0_8) # 使用内置格式 fig, ax plt.subpl…...

UIKit之图片浏览器
功能需求 实现一个图片浏览器,点击左右按钮可以切换背景图,且更新背景图对应的索引页和图片描述内容。 分析: 实现一个UIView的子类即可,该子类包含多个按钮。 实现步骤: 使用OC语言,故创建cocoa Touch类…...

如何查看SNMP设备的OID
什么是OID和MIB OID OID 代表对象标识符。 OID 唯一地标识 MIB 层次结构中的托管对象。 这可以被描述为一棵树,其级别由不同的组织分配。MIB MIB(管理信息基)提供数字化OID到可读文本的映射。 使用MIB Browser扫描OID 我的设备是一台UPS SN…...

什么?你设计接口什么都不考虑?
如果让你设计一个接口,你会考虑哪些问题? 1.接口参数校验 接口的入参和返回值都需要进行校验。 入参是否不能为空,入参的长度限制是多少,入参的格式限制,如邮箱格式限制 返回值是否为空,如果为空的时候是…...

2024年3月 青少年等级考试机器人理论真题二级
202403 青少年等级考试机器人理论真题二级 第 1 题 一个机器小车,用左右两个电机分别控制左右车轮,左侧电机转速是100rpm,右侧电机转速是50rpm,则此机器小车?( ) A:原地右转 B&am…...

C语言学习【printf函数和scanf函数】
C语言学习【printf函数和scanf函数】 printf()函数和scanf()函数可以让用户与程序交流,是输入/输出函数 printf()函数 请求printf()函数打印数据的指令要与待打印数据的类型相匹配。例如,打印整数时使用%d,打印字符时使用%c。这些符号被称…...

shell正则表达式
sort命令 以行为单位对文件内容进行排序,也可以根据不同的数据类型来排序 比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。 sort 对行内容进行升序排序 XXX | sort 选项 sort 选项 文件 常用选项&#x…...

react组件渲染性能优化之函数组件-useCallback使用
useCallback主要就是对函数进行缓存,useCallBack这个Hooks主要是解决React.memo不能缓存事件的问题 useCallBack(fn, dependencies) :fn想要缓存的函数,dependencies有关是否更新 fn 的所有响应式值的一个列表 比如:UseCallBackOptimize组件…...

【C++】:string类的基本使用
目录 引言一,string类对象的常见构造二,string类对象的容量操作三,string类对象的访问及遍历操作四,string类对象的修改操作五,string类非成员函数六,整形与字符串的转换 引言 string 就是我们常说的"…...

多线程的代码案例
目录 单例模式 饿汉模式 懒汉模式 阻塞队列 生产者消费者模型意义: 阻塞队列使用方法 实现阻塞队列 阻塞队列实现生产者消费者模型 定时器 实现简单的定时器 工厂模式 线程池 为啥呢? 从池子里面取 比 创建线程 效率更高 线程池的创建 怎么填坑 ThreadPoolExec…...

什么是Java中的设计模式?请列举几种常见的设计模式
一、引言 在软件开发中,设计模式是解决特定设计问题的最佳实践或通用解决方案。Java作为一种广泛使用的编程语言,其设计模式在软件设计和架构中起着至关重要的作用。设计模式不仅提高了代码的可读性和可维护性,还使得代码更加灵活和可扩展。…...

绘制奇迹:Processing中的动态图形与动画
🚀 欢迎回到Processing的世界,你的艺术编程航程刚刚开始。在我们的入门篇中,你已经学会了如何用Processing绘制基本的静态图形。现在,让我们一起探索Processing强大的动态图形和动画功能,释放你的创造力,走…...

Django视图Views
Views视图 HttpRequest 和HttpResponse Django中的视图主要用来接受web请求,并做出响应。视图的本质就是一个Python中的函数视图的响应分为两大类 1)以Json数据形式返回(JsonResponse) 2)以网页的形式返回 2.1)重定向到另一个网页 (HttpRe…...

国内智能搜索工具实战教程
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...

WebSocket or SSE?即时通讯的应用策略【送源码】
最近在研究H5推送,发现除了我们常用的WebSocket以外,其实还有一种协议也能实现H5推送,那就是SSE协议。 而且,当前主流的大模型平台,比如ChatGPT、通义千问、文心一言,对话时采用的就是SSE。 什么是SSE协议…...