python量化分析教程 | 最近几年A股养老基金整体盈亏情况分析

股票李魔佛 发表了文章 • 0 个评论 • 25 次浏览 • 2024-07-25 17:30 • 来自相关话题

这几年A股股市走势有目共睹。跌的让人头晕目眩。

不仅是散户被深套,很多基金也都大幅亏损。甚至前阵子看到证券时报报道,养老目标基金都出现不是清盘的现象。







于是笔者好奇心驱使,想看看这些养老基金最近几年的盈利情况,会不会把长辈老人们的下半辈子养老金都亏空了。

作为一名授人以渔的公众号博主,不仅仅贴个收益率图出来这么简单的啦。如果只是想看数据,直接跳过前面的操作即可。

笔者手把手教大家做数据分析,学会后不仅仅只对养老基金这一类别的基金做分析,还可以对不同类型的基金做分析。

前提:电脑按照了python已经相关库(jupyter notebook,pandas,akshare)

数据源:天天基金网

打开东财的天天基金网(https://fund.eastmoney.com/),在基金搜索页面输入:养老






总共有515个与养老相关的公募基金。如果没显示全,点击下图里面的“点击展开更多”按钮








抓包就找到对应的URL地址了,如下:https://fundsuggest.eastmoney.com/FundSearch/api/FundSearchPageAPI.ashx?callback=jQuery18306906210160165065_1721823304653&m=1&key=养老&pageindex=0&pagesize=515&_=1721823360126 
 
如果你想分析其他类型的主题基金,只需要把上面的url里面的key=养老,换成其他的就可以了,比如 key=芯片

浏览器输入上面的URL就可以拿到数据了。







简单起见,我就不写爬取数据的代码,直接复制粘贴浏览器返回的内容就好了。

然后把前面起始的jQuery18306906210160165065_1721823304653( 和最后的括号去掉,就得到一个json数据了。
 
js_data = {
"ErrCode": 0,
"ErrMsg": "0",
"Datas": [
{
"_id": "001171",
"CODE": "001171",
"NAME": "工银养老产业股票A",
"STOCKMARKET": "",
"NEWTEXCH": ""
},
......... # 省略若干
]
}
 
(文末提供这个数据文件的获取方式)

接着写一个函数获取某个基金的当前收益率:目前就获取最近3年的收益率。
import akshare as ak

def get_fund_info(code,name):
fund_open_fund_info_em_df = ak.fund_open_fund_info_em(symbol=code, indicator="累计收益率走势",period="3年")
latest_perf = fund_open_fund_info_em_df.iloc[-1]['累计收益率']
return {'code':code,'profit':latest_perf,'name':name}
 
可以改动period='5年', ’10年‘,’成立以来',从而获取不同区间的收益率

接着把500多个基金遍历一遍就OK了。
fund_perf_list = []
for item in js_data['Datas']:
print('processing code {}'.format(item['CODE']))
try:
fund_perf_list.append(get_fund_info(item['CODE'],item['NAME']))
time.sleep(0.5)
except Exception as e:
print('error in processing code {}'.format(item['CODE']))
print(e)





 
 
然后去倒杯茶,慢慢等它跑完。







数据分析

把数据转为dataframe,按照收益率排名
import pandas as pd
df = pd.DataFrame(fund_perf_list)

rank_df = df.sort_values(by='profit')





 
 
也可以导出到excel
 
rank_df.to_excel('亏麻的养老基金.xlsx')





 
 
亏损最多的鹏华养老产业股票,最近3年亏损了-53%,不过它应该也不属于养老基金范畴,只是买的养老产业的股票。

而华夏养老2055五年持有混合(FOF)A 011745,这种才是标准的养老基金,这些养老基金大部分是FOF(它们持有标的是基金,而不是股票)







2021年成立,买入后还要锁定5年,期间不可卖出,老人们被套牢了也无法割肉了。成立以来亏损了-34%,近3年亏损了-41%。

于是笔者继续过滤一下,找出里面的全部FOF基金
 
fof_fund_df = rank_df[rank_df['name'].str.contains('FOF')]
 
 
得到下面的养老基金FOF全部数据















然后使用describe函数看看大体的涨跌幅情况:







总共有484个数据,平均涨幅为-8.38%

中位数是-6.13%。

涨幅最大的是4.85%,中欧预见平衡养老三年持有混合发起(FOF)Y

打开详情一看,原来是得益于成立得晚的缘故,而该基金是今年2月成立的。








最近3年沪深300指数跌了32%,而这个跌幅可以在485只养老基金里面排到了477名。聊以慰藉的是,绝大部分的养老基金在下跌行情下是跑赢了沪深300的。

绘制直方图

直方图可以一览数据得养老基金涨跌幅分布情况:
 
fof_fund_df.plot(kind='hist',bins=20,y='profit',width=2,grid=True)





 
从图可以看到,大部分养老基金的涨跌幅落在-20到0之间。
亏损达到-30%以上的其实也不是很多。
 
整体来说,养老基金FOF比买入主流宽基波动要小一些,但并非保本的理财工具,对于风险接受能力低的老一辈朋友,需要慎重考虑的。
 
原文数据可在公众号:
可转债量化分析
获取
  查看全部
这几年A股股市走势有目共睹。跌的让人头晕目眩。

不仅是散户被深套,很多基金也都大幅亏损。甚至前阵子看到证券时报报道,养老目标基金都出现不是清盘的现象。

20240724203835.png



于是笔者好奇心驱使,想看看这些养老基金最近几年的盈利情况,会不会把长辈老人们的下半辈子养老金都亏空了。

作为一名授人以渔的公众号博主,不仅仅贴个收益率图出来这么简单的啦。如果只是想看数据,直接跳过前面的操作即可。

笔者手把手教大家做数据分析,学会后不仅仅只对养老基金这一类别的基金做分析,还可以对不同类型的基金做分析。

前提:电脑按照了python已经相关库(jupyter notebook,pandas,akshare)

数据源:天天基金网

打开东财的天天基金网(https://fund.eastmoney.com/),在基金搜索页面输入:养老

20240724201831.png


总共有515个与养老相关的公募基金。如果没显示全,点击下图里面的“点击展开更多”按钮


20240724205640.png



抓包就找到对应的URL地址了,如下:https://fundsuggest.eastmoney.com/FundSearch/api/FundSearchPageAPI.ashx?callback=jQuery18306906210160165065_1721823304653&m=1&key=养老&pageindex=0&pagesize=515&_=1721823360126 
 
如果你想分析其他类型的主题基金,只需要把上面的url里面的key=养老,换成其他的就可以了,比如 key=芯片

浏览器输入上面的URL就可以拿到数据了。

20240724201909.png



简单起见,我就不写爬取数据的代码,直接复制粘贴浏览器返回的内容就好了。

然后把前面起始的jQuery18306906210160165065_1721823304653( 和最后的括号去掉,就得到一个json数据了。
 
js_data = {
"ErrCode": 0,
"ErrMsg": "0",
"Datas": [
{
"_id": "001171",
"CODE": "001171",
"NAME": "工银养老产业股票A",
"STOCKMARKET": "",
"NEWTEXCH": ""
},
......... # 省略若干
]
}

 
(文末提供这个数据文件的获取方式)

接着写一个函数获取某个基金的当前收益率:目前就获取最近3年的收益率。
import akshare as ak

def get_fund_info(code,name):
fund_open_fund_info_em_df = ak.fund_open_fund_info_em(symbol=code, indicator="累计收益率走势",period="3年")
latest_perf = fund_open_fund_info_em_df.iloc[-1]['累计收益率']
return {'code':code,'profit':latest_perf,'name':name}

 
可以改动period='5年', ’10年‘,’成立以来',从而获取不同区间的收益率

接着把500多个基金遍历一遍就OK了。
fund_perf_list = []
for item in js_data['Datas']:
print('processing code {}'.format(item['CODE']))
try:
fund_perf_list.append(get_fund_info(item['CODE'],item['NAME']))
time.sleep(0.5)
except Exception as e:
print('error in processing code {}'.format(item['CODE']))
print(e)


20240725000417.png

 
 
然后去倒杯茶,慢慢等它跑完。

20240725000859.png



数据分析

把数据转为dataframe,按照收益率排名
import pandas as pd
df = pd.DataFrame(fund_perf_list)

rank_df = df.sort_values(by='profit')


20240725001101.png

 
 
也可以导出到excel
 
rank_df.to_excel('亏麻的养老基金.xlsx')


20240725001443.png

 
 
亏损最多的鹏华养老产业股票,最近3年亏损了-53%,不过它应该也不属于养老基金范畴,只是买的养老产业的股票。

而华夏养老2055五年持有混合(FOF)A 011745,这种才是标准的养老基金,这些养老基金大部分是FOF(它们持有标的是基金,而不是股票)


20240725002300.png


2021年成立,买入后还要锁定5年,期间不可卖出,老人们被套牢了也无法割肉了。成立以来亏损了-34%,近3年亏损了-41%。

于是笔者继续过滤一下,找出里面的全部FOF基金
 
fof_fund_df = rank_df[rank_df['name'].str.contains('FOF')]

 
 
得到下面的养老基金FOF全部数据


20240725003008.png




20240725003419.png



然后使用describe函数看看大体的涨跌幅情况:

20240725003134.png



总共有484个数据,平均涨幅为-8.38%

中位数是-6.13%。

涨幅最大的是4.85%,中欧预见平衡养老三年持有混合发起(FOF)Y

打开详情一看,原来是得益于成立得晚的缘故,而该基金是今年2月成立的。


20240725003530.png



最近3年沪深300指数跌了32%,而这个跌幅可以在485只养老基金里面排到了477名。聊以慰藉的是,绝大部分的养老基金在下跌行情下是跑赢了沪深300的。

绘制直方图

直方图可以一览数据得养老基金涨跌幅分布情况:
 
fof_fund_df.plot(kind='hist',bins=20,y='profit',width=2,grid=True)


output.png

 
从图可以看到,大部分养老基金的涨跌幅落在-20到0之间。
亏损达到-30%以上的其实也不是很多。
 
整体来说,养老基金FOF比买入主流宽基波动要小一些,但并非保本的理财工具,对于风险接受能力低的老一辈朋友,需要慎重考虑的。
 
原文数据可在公众号:
可转债量化分析
获取
 

优矿的回测引擎运行在python2.7,汗

李魔佛 发表了文章 • 0 个评论 • 44 次浏览 • 2024-07-22 11:59 • 来自相关话题

之前看到优矿的报错提示如下:

回测引擎运行在 Python2.7 之上,请您使用 Python2.7 的写法进行策略编写。
 
居然回测引擎还在2.7,怪不得目前性能比较拉跨了呢。。。
 
不过话说,自从它的可转债数据收费之后,我就一直没有再使用优矿进行回测了。
 
  查看全部
之前看到优矿的报错提示如下:

回测引擎运行在 Python2.7 之上,请您使用 Python2.7 的写法进行策略编写。
 
居然回测引擎还在2.7,怪不得目前性能比较拉跨了呢。。。
 
不过话说,自从它的可转债数据收费之后,我就一直没有再使用优矿进行回测了。
 
 

华宝证券 华宝期权宝 钱龙 客户端 无法下载的原因

股票李魔佛 发表了文章 • 0 个评论 • 161 次浏览 • 2024-07-05 11:45 • 来自相关话题

本来想下载一个期权软件下来看看T型交易图。
 
结果在华宝的官网 找到下载链接,但一直报错:





 
似乎其他软件也是报错。
 
500报错,应该是服务器的原因。
 
然后把链接复制下来:
 
https://download.cnhbstock.com/download/qlqqb/qlqqbpc/qqbfz.exe
 
把链接的https 改成 http,
 
浏览器会提示:
您的连接不是私密连接
攻击者可能会试图从 139.224.24.109 窃取您的信息(例如:密码、通讯内容或信用卡信息)。了解详情
NET::ERR_CERT_COMMON_NAME_INVALID
如果您想获得 Chrome 最高级别然后点击继续访问

 
结果就可以下载啦。
 
说实话,华宝这技术的确不咋地。
 
这个问题居然没有反馈,没有人去修复吗?
 
  查看全部
本来想下载一个期权软件下来看看T型交易图。
 
结果在华宝的官网 找到下载链接,但一直报错:

20240705114345.png

 
似乎其他软件也是报错。
 
500报错,应该是服务器的原因。
 
然后把链接复制下来:
 
https://download.cnhbstock.com/download/qlqqb/qlqqbpc/qqbfz.exe
 
把链接的https 改成 http,
 
浏览器会提示:
您的连接不是私密连接
攻击者可能会试图从 139.224.24.109 窃取您的信息(例如:密码、通讯内容或信用卡信息)。了解详情
NET::ERR_CERT_COMMON_NAME_INVALID
如果您想获得 Chrome 最高级别
然后点击继续访问

 
结果就可以下载啦。
 
说实话,华宝这技术的确不咋地。
 
这个问题居然没有反馈,没有人去修复吗?
 
 

ptrade获取的历史数据最长到哪一年?ptrade如何获取上证指数

Ptrade李魔佛 发表了文章 • 0 个评论 • 186 次浏览 • 2024-06-30 13:48 • 来自相关话题

Ptrade获取日线,分钟线数据最长可以到2005年。
文档里面也有说明:
 

7、该接口只能获取2005年后的数据。






ptrade官网api接口文档:
https://ptradeapi.com/#
 
实测也是符合要求的:
 
ptrade如何获取上证指数, 代码是  000001.SS
test_data = data = get_price(security='000001.SS',start_date='20050201',end_date='20050630',frequency='1d')
ptrade获取上证指数2005年的数据:
 





 
需要低佣,低门槛开通ptrade的朋友,可以扫描关注关注号: 查看全部
Ptrade获取日线,分钟线数据最长可以到2005年。
文档里面也有说明:
 


7、该接口只能获取2005年后的数据。



20240630134315.png

ptrade官网api接口文档:
https://ptradeapi.com/#
 
实测也是符合要求的:
 
ptrade如何获取上证指数, 代码是  000001.SS
test_data = data = get_price(security='000001.SS',start_date='20050201',end_date='20050630',frequency='1d')

ptrade获取上证指数2005年的数据:
 

20240630134443.png

 
需要低佣,低门槛开通ptrade的朋友,可以扫描关注关注号:

国金证券QMT测试客户端 - 获取可融券股票数据

回复

QMT李魔佛 回复了问题 • 1 人关注 • 1 个回复 • 292 次浏览 • 2024-06-19 10:53 • 来自相关话题

QMT获取持仓信息报错:AttributeError: 'NoneType' object has no attribute 'request_id'

QMT李魔佛 发表了文章 • 0 个评论 • 215 次浏览 • 2024-06-17 14:03 • 来自相关话题

这个是新手经常遇到的问题。读取持仓信息的时候报错:
代码如下:
 
 
原因就是不能init之前去读取
# encoding:gbk
'''
实盘可以执行
固定数量
'''
import datetime


ACCOUNT = ''


def init(ContextInfo):
ContextInfo.set_account(ACCOUNT)


def get_position_infos():
# 信用账户可用资金
position_infos = get_trade_detail_data(ACCOUNT, 'stock', 'position')


pos_dict={}
for pos in position_infos:
code = pos.m_strInstrumentID
if pos.m_nVolume > 0:
pos_dict[code] = pos.m_nVolume
return pos_dict

datax = get_position_infos() # 这里error

def handlebar(ContextInfo):
if ContextInfo.is_last_bar():
current = datetime.datetime.now().strftime('%H:%M:%S.%f')
print(datax)


datax = get_position_infos()  #这里error
这个函数再最开始的时候就被定义了。没有经过initial初始话函数,很多数据没有获取,从而导致的报错。
 欢迎关注交流

  查看全部
这个是新手经常遇到的问题。读取持仓信息的时候报错:
代码如下:
 
 
原因就是不能init之前去读取
# encoding:gbk
'''
实盘可以执行
固定数量
'''
import datetime


ACCOUNT = ''


def init(ContextInfo):
ContextInfo.set_account(ACCOUNT)


def get_position_infos():
# 信用账户可用资金
position_infos = get_trade_detail_data(ACCOUNT, 'stock', 'position')


pos_dict={}
for pos in position_infos:
code = pos.m_strInstrumentID
if pos.m_nVolume > 0:
pos_dict[code] = pos.m_nVolume
return pos_dict

datax = get_position_infos() # 这里error

def handlebar(ContextInfo):
if ContextInfo.is_last_bar():
current = datetime.datetime.now().strftime('%H:%M:%S.%f')
print(datax)


datax = get_position_infos()  #这里error
这个函数再最开始的时候就被定义了。没有经过initial初始话函数,很多数据没有获取,从而导致的报错。
 欢迎关注交流

 

QMT股票两融对冲建仓实盘

QMT李魔佛 发表了文章 • 0 个评论 • 654 次浏览 • 2024-05-29 12:02 • 来自相关话题

为了避免速度过快造成价格波动,提供速度,数量,延时控制。





 
成交了多少量,就融券多少量。达到指标即可停止。
 
代写量化程序,可以关注公众号,后台联系。 价格比QMT官网低的多了。实战性选手,选过N多QMT,ptrade实盘代码。
  查看全部
为了避免速度过快造成价格波动,提供速度,数量,延时控制。

20240529111758.png

 
成交了多少量,就融券多少量。达到指标即可停止。
 
代写量化程序,可以关注公众号,后台联系。 价格比QMT官网低的多了。实战性选手,选过N多QMT,ptrade实盘代码。
 

Ptrade成交回调函数无法执行的原因? | ptrade bug

Ptrade李魔佛 发表了文章 • 0 个评论 • 300 次浏览 • 2024-05-28 00:08 • 来自相关话题

目前的ptrade有一个隐藏很深的bug。
 
就是回调函数里面有一个字段entrust_no.
 
这个字段是什么意思呢? 是营业部的下单编号。比如你挂了一个委托单,就会有一个entrust_no, 比如 100001
 
这个编号对于一天的数据来说,是唯一不重复的,也就是一天内再不会出现100001。
 
而ptrade的成交回调依赖的是这个entrust_no, 如果系统里面已经触发过了一个entrust_no 为 100001的成交委托,那么如果又有一个重复的订单entrust_no 100001成交,那么,此时的ptrade的 成交回调函数是不会触发的!
 
那么上面说的一天内这个entrust_no是不会重复的。
 
可是,这个entrust_no挂单编号,在同一个营业部单元里,第二天会重复的,比如你第二天挂单也是entrust_no 100001,并且你的ptrade策略没有重启,也就是一直运行的话,那么如果碰巧你的下单entrust_no上昨天或者之前某一天(ptrade策略没有重启开始算起),entrust_no重复了的情况下。 
 
此时的ptrade 成交回调函数 on_trade_repsonse 是不会执行的!!!
 
天坑!
  查看全部
目前的ptrade有一个隐藏很深的bug。
 
就是回调函数里面有一个字段entrust_no.
 
这个字段是什么意思呢? 是营业部的下单编号。比如你挂了一个委托单,就会有一个entrust_no, 比如 100001
 
这个编号对于一天的数据来说,是唯一不重复的,也就是一天内再不会出现100001。
 
而ptrade的成交回调依赖的是这个entrust_no, 如果系统里面已经触发过了一个entrust_no 为 100001的成交委托,那么如果又有一个重复的订单entrust_no 100001成交,那么,此时的ptrade的 成交回调函数是不会触发的!
 
那么上面说的一天内这个entrust_no是不会重复的。
 
可是,这个entrust_no挂单编号,在同一个营业部单元里,第二天会重复的,比如你第二天挂单也是entrust_no 100001,并且你的ptrade策略没有重启,也就是一直运行的话,那么如果碰巧你的下单entrust_no上昨天或者之前某一天(ptrade策略没有重启开始算起),entrust_no重复了的情况下。 
 
此时的ptrade 成交回调函数 on_trade_repsonse 是不会执行的!!!
 
天坑!
 

迅投官网的实例代码好多问题,惨不忍睹

QMT李魔佛 发表了文章 • 0 个评论 • 354 次浏览 • 2024-05-12 16:55 • 来自相关话题

以前喜欢用C替代ContextInfo,现在改过去了,又有部分改的不完整。
 
还有更多的缩进的问题。
 





 
pep8的规范早已经不用tab来做缩进,而是用4个空格。
 
之前的文章里面也提到了,可以在qmt的配置文件里面改的。不过在UI上是不提供修改的地方。
http://www.30daydo.com/article/44602
  查看全部

20240512165205.png

以前喜欢用C替代ContextInfo,现在改过去了,又有部分改的不完整。
 
还有更多的缩进的问题。
 

20240512165415.png

 
pep8的规范早已经不用tab来做缩进,而是用4个空格。
 
之前的文章里面也提到了,可以在qmt的配置文件里面改的。不过在UI上是不提供修改的地方。
http://www.30daydo.com/article/44602
 

QMT里定时任务运行时间操作定时任务的间隔,会怎么样?

QMT李魔佛 发表了文章 • 0 个评论 • 362 次浏览 • 2024-05-06 10:32 • 来自相关话题

代码很简单,就是在run_time这个定期运行的任务里面,定期1秒执行一次任务
 







当时任务运行时间超过1秒钟,比如上面的代码里面用time.sleep(3) 模拟这个超时,等待3秒。

在tick 实盘模式下运行,输出什么的?

答案如下:








每次的start和end之间间隔了3秒钟,然后下一次的start和上一次start的间隔也是在3秒钟,也就是当然时刻的定时任务没有执行完成,下一个时刻的定时任务不会被执行。

那么有人会要求,不想要被运行时间长的任务阻碍了当前的任务,要怎么操作呢? 最简单的方式,加一个多线程就好了。

稍微改动一下上面的代码:







把要执行的任务,写成一个函数,然后使用threading.Thread去执行这个函数, t.star() 就是启动任务。








执行结果如上图,每次的start 间隔只有1秒,当时end是要等待3秒之后才打印出来。但end的输出不会阻塞当前的start输出,start稳定地1秒间隔输出一次,end也在当前start的3秒之后打印出来。
 
  查看全部
代码很简单,就是在run_time这个定期运行的任务里面,定期1秒执行一次任务
 

20240506101947.png



当时任务运行时间超过1秒钟,比如上面的代码里面用time.sleep(3) 模拟这个超时,等待3秒。

在tick 实盘模式下运行,输出什么的?

答案如下:


20240506101516.png



每次的start和end之间间隔了3秒钟,然后下一次的start和上一次start的间隔也是在3秒钟,也就是当然时刻的定时任务没有执行完成,下一个时刻的定时任务不会被执行。

那么有人会要求,不想要被运行时间长的任务阻碍了当前的任务,要怎么操作呢? 最简单的方式,加一个多线程就好了。

稍微改动一下上面的代码:

20240506101043.png



把要执行的任务,写成一个函数,然后使用threading.Thread去执行这个函数, t.star() 就是启动任务。


20240506101030.png



执行结果如上图,每次的start 间隔只有1秒,当时end是要等待3秒之后才打印出来。但end的输出不会阻塞当前的start输出,start稳定地1秒间隔输出一次,end也在当前start的3秒之后打印出来。
 
 

国盛证券的Ptrade数据无论是回测还是实盘很有问题,前复权不正确,数据断崖

Ptrade李魔佛 发表了文章 • 0 个评论 • 491 次浏览 • 2024-04-18 00:19 • 来自相关话题

连基本的历史数据都无法保证数据正确。
 
举个例子,比如 煤炭ETF 515220,





 
在4月12日进行的除权,1股变2股,因此,所以4月12日之后的价格会是原来的1/2,如果做前复权,那么前面的价格也都是要根据当前的价格做复权处理。
 
结果国盛的ptrade的历史数据,取的是前复权数据,前复权数据,(重点强调),在4月12日的的时候就出现了断崖。也就是没有做复权的处理。





 
测试代码很简单:
def initialize(context):
run_daily(context, event, '09:38')


def handle_data(context, data):
pass


def event(context):
his60 = get_history(60, '1d', ['close'], ['515220.SS'], fq='pre', include=False)
print(his60)运行时间改成任意的就行。
 
获取历史数据用
get_history,取过去60天的前复权的数据。 然后就是断崖的数据。 已经确定是国盛的ptrade数据问题。因为我用上面的代码,在东莞证券,国金证券,湘财证券的ptrade上运行,均能得到正确的数据。
 
然后更为搞笑的,这么一个问题,反馈了,没有回应。无语。
 
 
  查看全部
连基本的历史数据都无法保证数据正确。
 
举个例子,比如 煤炭ETF 515220,

20240418001102.png

 
在4月12日进行的除权,1股变2股,因此,所以4月12日之后的价格会是原来的1/2,如果做前复权,那么前面的价格也都是要根据当前的价格做复权处理。
 
结果国盛的ptrade的历史数据,取的是前复权数据,前复权数据,(重点强调),在4月12日的的时候就出现了断崖。也就是没有做复权的处理。

微信图片_20240418001026.png

 
测试代码很简单:
def initialize(context):
run_daily(context, event, '09:38')


def handle_data(context, data):
pass


def event(context):
his60 = get_history(60, '1d', ['close'], ['515220.SS'], fq='pre', include=False)
print(his60)
运行时间改成任意的就行。
 
获取历史数据用
get_history,取过去60天的前复权的数据。 然后就是断崖的数据。 已经确定是国盛的ptrade数据问题。因为我用上面的代码,在东莞证券,国金证券,湘财证券的ptrade上运行,均能得到正确的数据。
 
然后更为搞笑的,这么一个问题,反馈了,没有回应。无语。
 
 
 

使用量化程序获取ETF的成分股与实时净值

QMT李魔佛 发表了文章 • 0 个评论 • 481 次浏览 • 2024-04-11 12:22 • 来自相关话题

代码只有几行:
# coding:gbk
def init(C):
pass

def handlebar(C):
iopv = get_etf_iopv("159928.SZ")
print(f'基金净值为{iopv}')
info = get_etf_info('513520.SH')
print(f'基金申购信息: {info}')
得到的数据如下:





 
需要开通低门槛量化QMT的朋友,可以扫码关注公众号开通: 查看全部
代码只有几行:
# coding:gbk
def init(C):
pass

def handlebar(C):
iopv = get_etf_iopv("159928.SZ")
print(f'基金净值为{iopv}')
info = get_etf_info('513520.SH')
print(f'基金申购信息: {info}')

得到的数据如下:

20240411122042.png

 
需要开通低门槛量化QMT的朋友,可以扫码关注公众号开通:

QMT回测会跳过当前的周六日和节假日吗

QMT李魔佛 发表了文章 • 0 个评论 • 432 次浏览 • 2024-04-09 13:13 • 来自相关话题

使用的handle_bar进行回测,它是会自动跳过周六日和节假日的。
比如回测日期选择 2024年3月28日到2024年4月2日。
其中3月30日和31日是周六日。
下面回测的数据是不执行这两天的数据。从3月30日 15:00的数据,下一个bar就是4月1日09:30了




需要低门槛开通量化QMT,Ptrade,可以扫码联系。
开通后可加入技术交流群。 查看全部
使用的handle_bar进行回测,它是会自动跳过周六日和节假日的。
比如回测日期选择 2024年3月28日到2024年4月2日。
其中3月30日和31日是周六日。
下面回测的数据是不执行这两天的数据。从3月30日 15:00的数据,下一个bar就是4月1日09:30了
20240409130951.png

需要低门槛开通量化QMT,Ptrade,可以扫码联系。
开通后可加入技术交流群。

qmt下载完数据之后,记得重启一次qmt,不然get_market_data_ex依然还是获取不到数据的

QMT李魔佛 发表了文章 • 0 个评论 • 510 次浏览 • 2024-04-01 13:38 • 来自相关话题

最近群里问这个问题的人比较多。
 
qmt下载完数据之后,get_market_data_ex依然还是获取不到数据。
 
其实主要数据没有刷新。
 
只需要你手动关闭QMT,再打开一次就好了。
 





 
反正呢,这些问题,QMT也不会告诉你,要靠自己摸索了。
 
欢迎收藏网站哦! 查看全部
最近群里问这个问题的人比较多。
 
qmt下载完数据之后,get_market_data_ex依然还是获取不到数据。
 
其实主要数据没有刷新。
 
只需要你手动关闭QMT,再打开一次就好了。
 

20240401133759.png

 
反正呢,这些问题,QMT也不会告诉你,要靠自己摸索了。
 
欢迎收藏网站哦!

QMT每次自动升级,都会把改过的配置文件给覆盖掉

QMT李魔佛 发表了文章 • 0 个评论 • 520 次浏览 • 2024-03-31 14:23 • 来自相关话题

太业余。
感觉设计模式有问题。
 
本来我配置了缩进用的4个空格,(这是pep8的标准好吧)
而qmt默认是用tab做缩进。
 
导致从vs code或者pycharm上的代码迁移迁移过来qmt的编辑器,你按tab键,是制表符,而不是4个空格。
 
运行或者回测就会报错。





 
每次升级都把我的配置给改了。
 
难道不覆盖config文件不行吗? 每次类似全量升级,一点点bug fix都在全量升级
  查看全部
太业余。
感觉设计模式有问题。
 
本来我配置了缩进用的4个空格,(这是pep8的标准好吧)
而qmt默认是用tab做缩进。
 
导致从vs code或者pycharm上的代码迁移迁移过来qmt的编辑器,你按tab键,是制表符,而不是4个空格。
 
运行或者回测就会报错。

20240331004.png

 
每次升级都把我的配置给改了。
 
难道不覆盖config文件不行吗? 每次类似全量升级,一点点bug fix都在全量升级
 

不同券商的数据质量简单对比:国金QMT vs 国信QMT(iquant)

QMT李魔佛 发表了文章 • 0 个评论 • 1024 次浏览 • 2024-03-31 11:57 • 来自相关话题

同一段代码,先在国信上跑回测,先获取可转债的1分钟的分笔数据,发现一些时间段里的成交额居然是0. (数据已经先下载好了)

点击打开大图





上面的amount字段(成交额),返回的是0。

看了一下对应的转债,没有停牌,是有正常数据交易的。

然后用国金的QMT记性交叉验证。同样的代码
点击打开大图




 
国金的是正常的。只是成交量的小数浮点位是不是有点多了? 可能用的numy的默认9位,没有做处理而已。

【在写这个文章的时候发现国信的qmt的volume成交量是有数据的,那么其实可以用价格x成交量=成交额,间接获取成交额,大坑】

点击打开大图




 
附测试源码:
 # coding:gbk
# 公众号:可转债量化分析
DEBUG = True
import time
def get_datetime(ContextInfo):
# 获取当前时间
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
date = timetag_to_datetime(realtime, "%Y-%m-%d %H:%M:%S")
if DEBUG:
print('当前日期 ', date)
return date

def init(ContextInfo):
print("==============start==========")
ContextInfo.start = '2024-03-27 10:00:00'
ContextInfo.end = '2024-03-29 10:00:00'
#
#ContextInfo.end = '2023-01-05'
#ContextInfo.start = '2023-01-16'
print('init')

def handlebar(ContextInfo):
# 回测的时候不需要
#if not ContextInfo.is_last_bar():
# print('return')
# return
get_datetime(ContextInfo)
print('handlebar')
data = ContextInfo.get_market_data(['quoter'], stock_code = ['123167.SZ'], skip_paused = True, period = 'tick', dividend_type = 'front')

#data = ContextInfo.get_market_data(['close'], stock_code = ['113567.SH'], skip_paused = True, period = '1d', dividend_type = 'front')
#print(type(data))
print(data)

def stop(ContextInfo):
print( 'strategy is stop !') 查看全部
同一段代码,先在国信上跑回测,先获取可转债的1分钟的分笔数据,发现一些时间段里的成交额居然是0. (数据已经先下载好了)

点击打开大图
20240331002.png


上面的amount字段(成交额),返回的是0。

看了一下对应的转债,没有停牌,是有正常数据交易的。

然后用国金的QMT记性交叉验证。同样的代码
点击打开大图
20240331001.png

 
国金的是正常的。只是成交量的小数浮点位是不是有点多了? 可能用的numy的默认9位,没有做处理而已。

【在写这个文章的时候发现国信的qmt的volume成交量是有数据的,那么其实可以用价格x成交量=成交额,间接获取成交额,大坑】

点击打开大图
20240331003.png

 
附测试源码:
 
# coding:gbk
# 公众号:可转债量化分析
DEBUG = True
import time
def get_datetime(ContextInfo):
# 获取当前时间
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
date = timetag_to_datetime(realtime, "%Y-%m-%d %H:%M:%S")
if DEBUG:
print('当前日期 ', date)
return date

def init(ContextInfo):
print("==============start==========")
ContextInfo.start = '2024-03-27 10:00:00'
ContextInfo.end = '2024-03-29 10:00:00'
#
#ContextInfo.end = '2023-01-05'
#ContextInfo.start = '2023-01-16'
print('init')

def handlebar(ContextInfo):
# 回测的时候不需要
#if not ContextInfo.is_last_bar():
# print('return')
# return
get_datetime(ContextInfo)
print('handlebar')
data = ContextInfo.get_market_data(['quoter'], stock_code = ['123167.SZ'], skip_paused = True, period = 'tick', dividend_type = 'front')

#data = ContextInfo.get_market_data(['close'], stock_code = ['113567.SH'], skip_paused = True, period = '1d', dividend_type = 'front')
#print(type(data))
print(data)

def stop(ContextInfo):
print( 'strategy is stop !')

国金证券的融券数量多吗?什么是专项券源?

股票李魔佛 发表了文章 • 0 个评论 • 498 次浏览 • 2024-03-30 17:13 • 来自相关话题

因为国金的两融开通太方便了,不用跑柜台。app就可以开通,而且融资利率低,5%。
 
那么融券呢?
 
今天特意问了下经理,他发了一个融券的表格给我。
 





 
目前国金里面一般开通了融资融券的投资者,可用的券源有290个左右,随借随还的。说实话,这个数量不算太多。
 
而且里面的个股,部分也只能融100股,几百股的。所以即使被你融到券,实际下来的绝对收益也不会太高。
 
不过它也有一个专项券源。
它有资金要求,前20个交易日日均资产不低于300万元,才能够申请。
 
发现里面的券,主要是深圳交易所的为主,占了90%以上。





 
而且专项券源里面的可融券数量也比普通券源的要多很多,几千股,上万股的。
 
公共券源 :
实时可借 ,随时可融券卖出, 随借随还,融券卖出开仓后最快下一交易日方可归还融券负债 信用账户融券费率 按使用天数计息,算头不算尾
 
操作步骤: 融券卖出(所有客户端)
 
 
专项券源:
 实时可借 ,审批划拨成功后当日专项融券卖出, 固定期限(一般28天以内),不可提前归还 ;
专项融券头寸占用费率 : 按专项头寸合约期限计息,不论合约期限内客户是否使用券源,均需支付专项头寸合约占用利息,算头算尾 
 
操作步骤:
第1步:专项融券头寸申请(佣金宝APP/国金太阳至强版)

第2步:专项融券卖出(佣金宝APP/国金太阳至强版)
 





  查看全部
因为国金的两融开通太方便了,不用跑柜台。app就可以开通,而且融资利率低,5%。
 
那么融券呢?
 
今天特意问了下经理,他发了一个融券的表格给我。
 

20240330170633.png

 
目前国金里面一般开通了融资融券的投资者,可用的券源有290个左右,随借随还的。说实话,这个数量不算太多。
 
而且里面的个股,部分也只能融100股,几百股的。所以即使被你融到券,实际下来的绝对收益也不会太高。
 
不过它也有一个专项券源。
它有资金要求,前20个交易日日均资产不低于300万元,才能够申请。
 
发现里面的券,主要是深圳交易所的为主,占了90%以上。

20240330171053.png

 
而且专项券源里面的可融券数量也比普通券源的要多很多,几千股,上万股的。
 
公共券源 :
实时可借 ,随时可融券卖出, 随借随还,融券卖出开仓后最快下一交易日方可归还融券负债 信用账户融券费率 按使用天数计息,算头不算尾
 
操作步骤: 融券卖出(所有客户端)
 
 
专项券源:
 实时可借 ,审批划拨成功后当日专项融券卖出, 固定期限(一般28天以内),不可提前归还 ;
专项融券头寸占用费率 : 按专项头寸合约期限计息,不论合约期限内客户是否使用券源,均需支付专项头寸合约占用利息,算头算尾 
 
操作步骤:
第1步:专项融券头寸申请(佣金宝APP/国金太阳至强版)

第2步:专项融券卖出(佣金宝APP/国金太阳至强版)
 

20240330171336.png

 

Ptrade|QMT|银行股息率轮动 实盘自动化交易

李魔佛 发表了文章 • 0 个评论 • 740 次浏览 • 2024-03-05 09:33 • 来自相关话题

看有没有人需要,前排占坑 -- Task -- 
看有没有人需要,前排占坑 -- Task -- 

miniQMT安装包路径 | 下载地址

QMT李魔佛 发表了文章 • 0 个评论 • 854 次浏览 • 2024-02-29 20:09 • 来自相关话题

安装好QMT之后,在QMT的设置里面选择安装python。
 
等待几分钟,python文件下载好了之后。
 
找到qmt的安装目录,
 
进去这里面
 
\bin.x64\Lib\site-packages\xtquant
 
把这个目录复制到你的python路径的site-package 下面, 就可以在你的python环境下运行miniQMT了。
 
当然首先还是要启动你的QMT客户端,勾选极速模式。 (不开的话连不到券商服务器,这以为这无法再linux上单独跑,wine额外另说)
 
比如下面的获取行情的示例代码,还有直接下单代码
 # 用前须知

## xtdata提供和MiniQmt的交互接口,本质是和MiniQmt建立连接,由MiniQmt处理行情数据请求,再把结果回传返回到python层。使用的行情服务器以及能获取到的行情数据和MiniQmt是一致的,要检查数据或者切换连接时直接操作MiniQmt即可。

## 对于数据获取接口,使用时需要先确保MiniQmt已有所需要的数据,如果不足可以通过补充数据接口补充,再调用数据获取接口获取。

## 对于订阅接口,直接设置数据回调,数据到来时会由回调返回。订阅接收到的数据一般会保存下来,同种数据不需要再单独补充。

# 代码讲解

# 从本地python导入xtquant库,如果出现报错则说明安装失败
from xtquant import xtdata
import time

# 设定一个标的列表
code_list = ["000001.SZ"]
# 设定获取数据的周期
period = "1d"

# 下载标的行情数据
if 1:
## 为了方便用户进行数据管理,xtquant的大部分历史数据都是以压缩形式存储在本地的
## 比如行情数据,需要通过download_history_data下载,财务数据需要通过
## 所以在取历史数据之前,我们需要调用数据下载接口,将数据下载到本地
for i in code_list:
xtdata.download_history_data(i,period=period,incrementally=True) # 增量下载行情数据(开高低收,等等)到本地

xtdata.download_financial_data(code_list) # 下载财务数据到本地
xtdata.download_sector_data() # 下载板块数据到本地
# 更多数据的下载方式可以通过数据字典查询

# 读取本地历史行情数据
history_data = xtdata.get_market_data_ex(,code_list,period=period,count=-1)
print(history_data)
print("=" * 20)

# 如果需要盘中的实时行情,需要向服务器进行订阅后才能获取
# 订阅后,get_market_data函数于get_market_data_ex函数将会自动拼接本地历史行情与服务器实时行情

# 向服务器订阅数据
for i in code_list:
xtdata.subscribe_quote(i,period=period,count=-1) # 设置count = -1来取到当天所有实时行情

# 等待订阅完成
time.sleep(1)

# 获取订阅后的行情
kline_data = xtdata.get_market_data_ex(,code_list,period=period)
print(kline_data)

# 获取订阅后的行情,并以固定间隔进行刷新,预期会循环打印10次
for i in range(10):
# 这边做演示,就用for来循环了,实际使用中可以用while True
kline_data = xtdata.get_market_data_ex(,code_list,period=period)
print(kline_data)
time.sleep(3) # 三秒后再次获取行情

# 如果不想用固定间隔触发,可以以用订阅后的回调来执行
# 这种模式下当订阅的callback回调函数将会异步的执行,每当订阅的标的tick发生变化更新,callback回调函数就会被调用一次
# 本地已有的数据不会触发callback

# 定义的回测函数
## 回调函数中,data是本次触发回调的数据,只有一条
def f(data):
# print(data)

code_list = list(data.keys()) # 获取到本次触发的标的代码

kline_in_callabck = xtdata.get_market_data_ex(,code_list,period = period) # 在回调中获取klines数据
print(kline_in_callabck)

for i in code_list:
xtdata.subscribe_quote(i,period=period,count=-1,callback=f) # 订阅时设定回调函数

# 使用回调时,必须要同时使用xtdata.run()来阻塞程序,否则程序运行到最后一行就直接结束退出了。
xtdata.run()





 
异步下单#coding:utf-8
import time, datetime, traceback, sys
from xtquant import xtdata
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
from xtquant import xtconstant

#定义一个类 创建类的实例 作为状态的容器
class _a():
pass
A = _a()
A.bought_list =
A.hsa = xtdata.get_stock_list_in_sector('沪深A股')

def interact():
"""执行后进入repl模式"""
import code
code.InteractiveConsole(locals=globals()).interact()
xtdata.download_sector_data()

def f(data):
now = datetime.datetime.now()
for stock in data:
if stock not in A.hsa:
continue
cuurent_price = data[stock]['lastPrice']
pre_price = data[stock]['lastClose']
ratio = cuurent_price / pre_price - 1 if pre_price > 0 else 0
if ratio > 0.09 and stock not in A.bought_list:
print(f"{now} 最新价 买入 {stock} 200股")
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_BUY, 200, xtconstant.LATEST_PRICE, -1, 'strategy_name', stock)
A.bought_list.append(stock)

class MyXtQuantTraderCallback(XtQuantTraderCallback):
def on_disconnected(self):
"""
连接断开
:return:
"""
print(datetime.datetime.now(),'连接断开回调')

def on_stock_order(self, order):
"""
委托回报推送
:param order: XtOrder对象
:return:
"""
print(datetime.datetime.now(), '委托回调', order.order_remark)


def on_stock_trade(self, trade):
"""
成交变动推送
:param trade: XtTrade对象
:return:
"""
print(datetime.datetime.now(), '成交回调', trade.order_remark)


def on_order_error(self, order_error):
"""
委托失败推送
:param order_error:XtOrderError 对象
:return:
"""
# print("on order_error callback")
# print(order_error.order_id, order_error.error_id, order_error.error_msg)
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")

def on_cancel_error(self, cancel_error):
"""
撤单失败推送
:param cancel_error: XtCancelError 对象
:return:
"""
print(datetime.datetime.now(), sys._getframe().f_code.co_name)

def on_order_stock_async_response(self, response):
"""
异步下单回报推送
:param response: XtOrderResponse 对象
:return:
"""
print(f"异步委托回调 {response.order_remark}")

def on_cancel_order_stock_async_response(self, response):
"""
:param response: XtCancelOrderResponse 对象
:return:
"""
print(datetime.datetime.now(), sys._getframe().f_code.co_name)

def on_account_status(self, status):
"""
:param response: XtAccountStatus 对象
:return:
"""
print(datetime.datetime.now(), sys._getframe().f_code.co_name)


if __name__ == '__main__':
print("start")
#指定客户端所在路径
path = r'D:\qmt\sp3\迅投极速交易终端 睿智融科版\userdata_mini'
# 生成session id 整数类型 同时运行的策略不能重复
session_id = int(time.time())
xt_trader = XtQuantTrader(path, session_id)
# 开启主动请求接口的专用线程 开启后在on_stock_xxx回调函数里调用XtQuantTrader.query_xxx函数不会卡住回调线程,但是查询和推送的数据在时序上会变得不确定
# 详见: http://docs.thinktrader.net/vip/pages/ee0e9b/#开启主动请求接口的专用线程
# xt_trader.set_relaxed_response_order_enabled(True)

# 创建资金账号为 800068 的证券账号对象
acc = StockAccount('800068', 'STOCK')
# 创建交易回调类对象,并声明接收回调
callback = MyXtQuantTraderCallback()
xt_trader.register_callback(callback)
# 启动交易线程
xt_trader.start()
# 建立交易连接,返回0表示连接成功
connect_result = xt_trader.connect()
print('建立交易连接,返回0表示连接成功', connect_result)
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功
subscribe_result = xt_trader.subscribe(acc)
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)

#这一行是注册全推回调函数 包括下单判断 安全起见处于注释状态 确认理解效果后再放开
# xtdata.subscribe_whole_quote(["SH", "SZ"], callback=f)
# 阻塞主线程退出
xt_trader.run_forever()
# 如果使用vscode pycharm等本地编辑器 可以进入交互模式 方便调试 (把上一行的run_forever注释掉 否则不会执行到这里)
interact()


需要开通miniQMT(低门槛,低费率)的朋友,
可以扫码联系:或者添加 技术公众号:

 
公众号:
 

 
  查看全部
安装好QMT之后,在QMT的设置里面选择安装python。
 
等待几分钟,python文件下载好了之后。
 
找到qmt的安装目录,
 
进去这里面
 
\bin.x64\Lib\site-packages\xtquant
 
把这个目录复制到你的python路径的site-package 下面, 就可以在你的python环境下运行miniQMT了。
 
当然首先还是要启动你的QMT客户端,勾选极速模式。 (不开的话连不到券商服务器,这以为这无法再linux上单独跑,wine额外另说)
 
比如下面的获取行情的示例代码,还有直接下单代码
 
# 用前须知

## xtdata提供和MiniQmt的交互接口,本质是和MiniQmt建立连接,由MiniQmt处理行情数据请求,再把结果回传返回到python层。使用的行情服务器以及能获取到的行情数据和MiniQmt是一致的,要检查数据或者切换连接时直接操作MiniQmt即可。

## 对于数据获取接口,使用时需要先确保MiniQmt已有所需要的数据,如果不足可以通过补充数据接口补充,再调用数据获取接口获取。

## 对于订阅接口,直接设置数据回调,数据到来时会由回调返回。订阅接收到的数据一般会保存下来,同种数据不需要再单独补充。

# 代码讲解

# 从本地python导入xtquant库,如果出现报错则说明安装失败
from xtquant import xtdata
import time

# 设定一个标的列表
code_list = ["000001.SZ"]
# 设定获取数据的周期
period = "1d"

# 下载标的行情数据
if 1:
## 为了方便用户进行数据管理,xtquant的大部分历史数据都是以压缩形式存储在本地的
## 比如行情数据,需要通过download_history_data下载,财务数据需要通过
## 所以在取历史数据之前,我们需要调用数据下载接口,将数据下载到本地
for i in code_list:
xtdata.download_history_data(i,period=period,incrementally=True) # 增量下载行情数据(开高低收,等等)到本地

xtdata.download_financial_data(code_list) # 下载财务数据到本地
xtdata.download_sector_data() # 下载板块数据到本地
# 更多数据的下载方式可以通过数据字典查询

# 读取本地历史行情数据
history_data = xtdata.get_market_data_ex(,code_list,period=period,count=-1)
print(history_data)
print("=" * 20)

# 如果需要盘中的实时行情,需要向服务器进行订阅后才能获取
# 订阅后,get_market_data函数于get_market_data_ex函数将会自动拼接本地历史行情与服务器实时行情

# 向服务器订阅数据
for i in code_list:
xtdata.subscribe_quote(i,period=period,count=-1) # 设置count = -1来取到当天所有实时行情

# 等待订阅完成
time.sleep(1)

# 获取订阅后的行情
kline_data = xtdata.get_market_data_ex(,code_list,period=period)
print(kline_data)

# 获取订阅后的行情,并以固定间隔进行刷新,预期会循环打印10次
for i in range(10):
# 这边做演示,就用for来循环了,实际使用中可以用while True
kline_data = xtdata.get_market_data_ex(,code_list,period=period)
print(kline_data)
time.sleep(3) # 三秒后再次获取行情

# 如果不想用固定间隔触发,可以以用订阅后的回调来执行
# 这种模式下当订阅的callback回调函数将会异步的执行,每当订阅的标的tick发生变化更新,callback回调函数就会被调用一次
# 本地已有的数据不会触发callback

# 定义的回测函数
## 回调函数中,data是本次触发回调的数据,只有一条
def f(data):
# print(data)

code_list = list(data.keys()) # 获取到本次触发的标的代码

kline_in_callabck = xtdata.get_market_data_ex(,code_list,period = period) # 在回调中获取klines数据
print(kline_in_callabck)

for i in code_list:
xtdata.subscribe_quote(i,period=period,count=-1,callback=f) # 订阅时设定回调函数

# 使用回调时,必须要同时使用xtdata.run()来阻塞程序,否则程序运行到最后一行就直接结束退出了。
xtdata.run()





 
异步下单
#coding:utf-8
import time, datetime, traceback, sys
from xtquant import xtdata
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
from xtquant import xtconstant

#定义一个类 创建类的实例 作为状态的容器
class _a():
pass
A = _a()
A.bought_list =
A.hsa = xtdata.get_stock_list_in_sector('沪深A股')

def interact():
"""执行后进入repl模式"""
import code
code.InteractiveConsole(locals=globals()).interact()
xtdata.download_sector_data()

def f(data):
now = datetime.datetime.now()
for stock in data:
if stock not in A.hsa:
continue
cuurent_price = data[stock]['lastPrice']
pre_price = data[stock]['lastClose']
ratio = cuurent_price / pre_price - 1 if pre_price > 0 else 0
if ratio > 0.09 and stock not in A.bought_list:
print(f"{now} 最新价 买入 {stock} 200股")
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_BUY, 200, xtconstant.LATEST_PRICE, -1, 'strategy_name', stock)
A.bought_list.append(stock)

class MyXtQuantTraderCallback(XtQuantTraderCallback):
def on_disconnected(self):
"""
连接断开
:return:
"""
print(datetime.datetime.now(),'连接断开回调')

def on_stock_order(self, order):
"""
委托回报推送
:param order: XtOrder对象
:return:
"""
print(datetime.datetime.now(), '委托回调', order.order_remark)


def on_stock_trade(self, trade):
"""
成交变动推送
:param trade: XtTrade对象
:return:
"""
print(datetime.datetime.now(), '成交回调', trade.order_remark)


def on_order_error(self, order_error):
"""
委托失败推送
:param order_error:XtOrderError 对象
:return:
"""
# print("on order_error callback")
# print(order_error.order_id, order_error.error_id, order_error.error_msg)
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")

def on_cancel_error(self, cancel_error):
"""
撤单失败推送
:param cancel_error: XtCancelError 对象
:return:
"""
print(datetime.datetime.now(), sys._getframe().f_code.co_name)

def on_order_stock_async_response(self, response):
"""
异步下单回报推送
:param response: XtOrderResponse 对象
:return:
"""
print(f"异步委托回调 {response.order_remark}")

def on_cancel_order_stock_async_response(self, response):
"""
:param response: XtCancelOrderResponse 对象
:return:
"""
print(datetime.datetime.now(), sys._getframe().f_code.co_name)

def on_account_status(self, status):
"""
:param response: XtAccountStatus 对象
:return:
"""
print(datetime.datetime.now(), sys._getframe().f_code.co_name)


if __name__ == '__main__':
print("start")
#指定客户端所在路径
path = r'D:\qmt\sp3\迅投极速交易终端 睿智融科版\userdata_mini'
# 生成session id 整数类型 同时运行的策略不能重复
session_id = int(time.time())
xt_trader = XtQuantTrader(path, session_id)
# 开启主动请求接口的专用线程 开启后在on_stock_xxx回调函数里调用XtQuantTrader.query_xxx函数不会卡住回调线程,但是查询和推送的数据在时序上会变得不确定
# 详见: http://docs.thinktrader.net/vip/pages/ee0e9b/#开启主动请求接口的专用线程
# xt_trader.set_relaxed_response_order_enabled(True)

# 创建资金账号为 800068 的证券账号对象
acc = StockAccount('800068', 'STOCK')
# 创建交易回调类对象,并声明接收回调
callback = MyXtQuantTraderCallback()
xt_trader.register_callback(callback)
# 启动交易线程
xt_trader.start()
# 建立交易连接,返回0表示连接成功
connect_result = xt_trader.connect()
print('建立交易连接,返回0表示连接成功', connect_result)
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功
subscribe_result = xt_trader.subscribe(acc)
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)

#这一行是注册全推回调函数 包括下单判断 安全起见处于注释状态 确认理解效果后再放开
# xtdata.subscribe_whole_quote(["SH", "SZ"], callback=f)
# 阻塞主线程退出
xt_trader.run_forever()
# 如果使用vscode pycharm等本地编辑器 可以进入交互模式 方便调试 (把上一行的run_forever注释掉 否则不会执行到这里)
interact()


需要开通miniQMT(低门槛,低费率)的朋友,
可以扫码联系:或者添加 技术公众号:

 
公众号:
 

 
 

银河证券1拖7

股票李魔佛 发表了文章 • 0 个评论 • 1110 次浏览 • 2024-02-23 15:16 • 来自相关话题

最近大家套利印度基金LOF如火如荼。
 
基本大家都用的银河证券或者华宝证券的1拖6,也就是一个证券账户,加挂 3个 深A,3个场内基金,6个账号可以同时申购 100元的印度基金。因为印度基金目前是限购状态,限购100元。
 
所以1拖6就可以申购600元。
 
目前每天稳定的溢价率为6-7%,一次的收益率为 6-7%,也就是30-40元一个账户一天。一周下来就有150-200元





 
 
这个看起来是个蚊子肉。
 
但如果你的证券账户足够多,比如你有10个证券账户(你女友,家人,亲戚,同事,朋友)
 
一周就有2000元。
 
所以限购套利的核心是 拖拉机+多账号
 
而很少人知道,其实可以1拖7,再多一个申购途径,就是场外申购。
 
比如支付宝,天天基金等渠道申购。不过要转入场内比较麻烦,而银河证券,华宝证券,内置了场外基金,可以很方便在券商app里面的场外基金买入(申购)。
 
步骤也很简单,





 
申购完成之后:





 
然后绑定场内和场外关系
 





 
然后要等T+2 之后,再在银河证券app里面 把印度基金从场外转到场内:





 
然后T+2之后,你的基金要继续等T+2之后才能到达你的证券账户。然后才能够在场内卖出。
 
所以通过场外转场内进行套利,要比场内支持申购,要晚2天到账的哦。
 
目前银河证券 低费率多多, 万0.854 免五,0.1元起,申购LOF基金1折,LOF卖出费率为万0.5,0.1元起。
逆回购1折。各个费率基本在同样档位里面是最低的了。
 
需要的朋友可以扫码联系开通: 查看全部
最近大家套利印度基金LOF如火如荼。
 
基本大家都用的银河证券或者华宝证券的1拖6,也就是一个证券账户,加挂 3个 深A,3个场内基金,6个账号可以同时申购 100元的印度基金。因为印度基金目前是限购状态,限购100元。
 
所以1拖6就可以申购600元。
 
目前每天稳定的溢价率为6-7%,一次的收益率为 6-7%,也就是30-40元一个账户一天。一周下来就有150-200元

微信图片_20240221114516.jpg

 
 
这个看起来是个蚊子肉。
 
但如果你的证券账户足够多,比如你有10个证券账户(你女友,家人,亲戚,同事,朋友)
 
一周就有2000元。
 
所以限购套利的核心是 拖拉机+多账号
 
而很少人知道,其实可以1拖7,再多一个申购途径,就是场外申购。
 
比如支付宝,天天基金等渠道申购。不过要转入场内比较麻烦,而银河证券,华宝证券,内置了场外基金,可以很方便在券商app里面的场外基金买入(申购)。
 
步骤也很简单,

微信图片_20240222124738.jpg

 
申购完成之后:

微信图片_20240222125035.jpg

 
然后绑定场内和场外关系
 

v2-6f50d47051bfa9b36e93b46319e3e002_1440w_副本_副本_副本.png

 
然后要等T+2 之后,再在银河证券app里面 把印度基金从场外转到场内:

微信图片_20240222124738_副本_副本.jpg

 
然后T+2之后,你的基金要继续等T+2之后才能到达你的证券账户。然后才能够在场内卖出。
 
所以通过场外转场内进行套利,要比场内支持申购,要晚2天到账的哦。
 
目前银河证券 低费率多多, 万0.854 免五,0.1元起,申购LOF基金1折,LOF卖出费率为万0.5,0.1元起。
逆回购1折。各个费率基本在同样档位里面是最低的了。
 
需要的朋友可以扫码联系开通:

QMT获取全市场股票,排除ST退市风险股票

QMT李魔佛 发表了文章 • 0 个评论 • 892 次浏览 • 2024-02-07 22:25 • 来自相关话题

因为QMT不能获取北交所的股票历史数据,所以也把北交所的股票也排除了。
 
def get_all_market_code(ContextInfo):

all_market_codes = [item for item in ContextInfo.get_stock_list_in_sector('沪深A股') if not item.endswith('BJ')]
return filter_ST_stock(ContextInfo, all_market_codes)


def filter_ST_stock(ContextInfo, code_list):
result = []
for code in code_list:
if re.search('(st)|(ST)|(\*st)|(\*ST)|(退)',ContextInfo.get_stock_name(code)):
print('排除 : ',ContextInfo.get_stock_name(code),code)
continue
result.append(code)
return result

global_dict = {}

def init(ContextInfo):
now = time.ctime()
print('策略初始化{}'.format(now))
need_download = 1
global_dict['start_date'] = '20231201'
global_dict['end_date'] = ''
global_dict['code_list'] = get_all_market_code(ContextInfo)

 有问题可以咨询公众号或者知识星球
提供策略代写服务
  查看全部
因为QMT不能获取北交所的股票历史数据,所以也把北交所的股票也排除了。
 
def get_all_market_code(ContextInfo):

all_market_codes = [item for item in ContextInfo.get_stock_list_in_sector('沪深A股') if not item.endswith('BJ')]
return filter_ST_stock(ContextInfo, all_market_codes)


def filter_ST_stock(ContextInfo, code_list):
result = []
for code in code_list:
if re.search('(st)|(ST)|(\*st)|(\*ST)|(退)',ContextInfo.get_stock_name(code)):
print('排除 : ',ContextInfo.get_stock_name(code),code)
continue
result.append(code)
return result

global_dict = {}

def init(ContextInfo):
now = time.ctime()
print('策略初始化{}'.format(now))
need_download = 1
global_dict['start_date'] = '20231201'
global_dict['end_date'] = ''
global_dict['code_list'] = get_all_market_code(ContextInfo)

 有问题可以咨询公众号或者知识星球
提供策略代写服务
 

QMT实时获取涨停股,筛选流通盘大于X的股票

QMT李魔佛 发表了文章 • 0 个评论 • 997 次浏览 • 2024-02-07 18:28 • 来自相关话题

基于官方例子修复了一下bug,比如移除了北交所的股票,因为目前qmt获取不了北交所的股票历史数据。
 
直接上代码:# coding:gbk
import time


class G():
pass


g = G()


def init(ContextInfo):
g.hsa = [item for item in ContextInfo.get_stock_list_in_sector('沪深A股') if not item.endswith('BJ')]
g.vol_dict = {}
for stock in g.hsa:
g.vol_dict[stock] = ContextInfo.get_last_volume(stock)
ContextInfo.run_time("execution", "1nSecond", "2019-10-14 13:20:00")


def execution(ContextInfo):
t0 = time.time()
full_tick = ContextInfo.get_full_tick(g.hsa)
total_market_value = 0
total_ratio = 0
count = 0
for stock in g.hsa:
if full_tick[stock]['lastClose'] == 0:
continue
ratio = full_tick[stock]['lastPrice'] / full_tick[stock]['lastClose'] - 1
rise_price = round(full_tick[stock]['lastClose'] * 1.2, 2) if stock[0] == '3' or stock[:3] == '688' else round(
full_tick[stock]['lastClose'] * 1.1, 2)
# 如果要打印涨停品种
if abs(full_tick[stock]['lastPrice'] - rise_price) <0.01:
print(f"涨停股票 {stock} {ContextInfo.get_stock_name(stock)}")

market_value = full_tick[stock]['lastPrice'] * g.vol_dict[stock]
total_ratio += ratio * market_value
total_market_value += market_value
count += 1
# print(count)
total_ratio /= total_market_value
total_ratio *= 100
print(f'A股加权涨幅 {round(total_ratio, 2)}% 函数运行耗时{round(time.time() - t0, 5)}秒')






 
欢迎关注公众号:
可转债量化分析 查看全部
基于官方例子修复了一下bug,比如移除了北交所的股票,因为目前qmt获取不了北交所的股票历史数据。
 
直接上代码:
# coding:gbk
import time


class G():
pass


g = G()


def init(ContextInfo):
g.hsa = [item for item in ContextInfo.get_stock_list_in_sector('沪深A股') if not item.endswith('BJ')]
g.vol_dict = {}
for stock in g.hsa:
g.vol_dict[stock] = ContextInfo.get_last_volume(stock)
ContextInfo.run_time("execution", "1nSecond", "2019-10-14 13:20:00")


def execution(ContextInfo):
t0 = time.time()
full_tick = ContextInfo.get_full_tick(g.hsa)
total_market_value = 0
total_ratio = 0
count = 0
for stock in g.hsa:
if full_tick[stock]['lastClose'] == 0:
continue
ratio = full_tick[stock]['lastPrice'] / full_tick[stock]['lastClose'] - 1
rise_price = round(full_tick[stock]['lastClose'] * 1.2, 2) if stock[0] == '3' or stock[:3] == '688' else round(
full_tick[stock]['lastClose'] * 1.1, 2)
# 如果要打印涨停品种
if abs(full_tick[stock]['lastPrice'] - rise_price) <0.01:
print(f"涨停股票 {stock} {ContextInfo.get_stock_name(stock)}")

market_value = full_tick[stock]['lastPrice'] * g.vol_dict[stock]
total_ratio += ratio * market_value
total_market_value += market_value
count += 1
# print(count)
total_ratio /= total_market_value
total_ratio *= 100
print(f'A股加权涨幅 {round(total_ratio, 2)}% 函数运行耗时{round(time.time() - t0, 5)}秒')


20240207182920.png

 
欢迎关注公众号:
可转债量化分析

迅投QMT投研版 有必要开吗?

QMT李魔佛 发表了文章 • 0 个评论 • 940 次浏览 • 2024-02-06 15:03 • 来自相关话题

没必要。
处处透出一股割韭菜的味道。
 
到处拉人进群,然后群里问问题,他们会让你私聊,加你,说服你开通投研版。
 
投研版无非多一些数据,你用tushare或者自己爬虫就可以获取,他们非要放到投研版里面,付费使用。
 
价格是一年8,9千,感觉没有一点性价比。
 
qmt,minniqmt有交易功能,有数据获取功能,也可以自己接入外部数据。没必要花那些冤枉钱去按年付费买一个不实用的数据。
真的没有数据,或者没有能力获取,付费找人写个api接口,爬虫数据,也不贵。 可以终身使用。 不好过按年付费???
 
关键那群qmt的人水平也不咋地,看他们的文档就知道,变量用A,B,C,D,人品也不咋地,星球上还抄袭我的星球文章,足以说明水平和人品。





 
群里问点问题,就让你开个投研版咨询哈。 还不如来我的qmt ptrade技术群的,free且有求必应哈。
  查看全部
没必要。
处处透出一股割韭菜的味道。
 
到处拉人进群,然后群里问问题,他们会让你私聊,加你,说服你开通投研版。
 
投研版无非多一些数据,你用tushare或者自己爬虫就可以获取,他们非要放到投研版里面,付费使用。
 
价格是一年8,9千,感觉没有一点性价比。
 
qmt,minniqmt有交易功能,有数据获取功能,也可以自己接入外部数据。没必要花那些冤枉钱去按年付费买一个不实用的数据。
真的没有数据,或者没有能力获取,付费找人写个api接口,爬虫数据,也不贵。 可以终身使用。 不好过按年付费???
 
关键那群qmt的人水平也不咋地,看他们的文档就知道,变量用A,B,C,D,人品也不咋地,星球上还抄袭我的星球文章,足以说明水平和人品。

Screenshot_2024_0206_150138.jpg

 
群里问点问题,就让你开个投研版咨询哈。 还不如来我的qmt ptrade技术群的,free且有求必应哈。
 

qmt获取北交所实时行情数据

QMT李魔佛 发表了文章 • 0 个评论 • 835 次浏览 • 2024-01-24 13:39 • 来自相关话题

之前没有试过用qmt交易北交所的股票,后面闻了一下券商,他们说是qmt支持北交所股票交易。
 
首先试试获取实时的行情:
我获取的是这个北交所股票的数据:






获取北交所行情数据如下:
 
#-*-coding:gbk-*-
import datetime
code = '838402.BJ'
def init(ContextInfo):
now = datetime.datetime.now()
print(now)

def handlebar(ContextInfo):
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
date = timetag_to_datetime(realtime, "%Y-%m-%d %H:%M:%S")
info = ContextInfo.get_full_tick(stock_code=["838402.BJ"])
print(info)
返回下面的数据:





 
对了下时间戳,是正确的。
 
然后试了下获取北交所的历史数据行情:
#-*-coding:gbk-*-
import datetime

code = '838402.BJ'
def init(ContextInfo):
now = datetime.datetime.now()
print(now)
download_history_data(code,"1d","20240105","")

def handlebar(ContextInfo):
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
date = timetag_to_datetime(realtime, "%Y-%m-%d %H:%M:%S")
print(date)
hist = ContextInfo.get_market_data_ex(['close'],[code], period = "1d",count = 1)
print(hist)

代码里面我想用 download_history_data(code,"1d","20240105","") 下载历史数据。
在数据目录里面也能够获取到这个股票的历史数据文件。
 
可是在qmt里面却输出的是个空的dataframe。






数据目录下面是有数据的。。




感觉是qmt里面的功能还没有完善对北交所股票的支持。
  查看全部
之前没有试过用qmt交易北交所的股票,后面闻了一下券商,他们说是qmt支持北交所股票交易。
 
首先试试获取实时的行情:
我获取的是这个北交所股票的数据:

20240124132926.png


获取北交所行情数据如下:
 
#-*-coding:gbk-*-
import datetime
code = '838402.BJ'
def init(ContextInfo):
now = datetime.datetime.now()
print(now)

def handlebar(ContextInfo):
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
date = timetag_to_datetime(realtime, "%Y-%m-%d %H:%M:%S")
info = ContextInfo.get_full_tick(stock_code=["838402.BJ"])
print(info)

返回下面的数据:

20240124132856.png

 
对了下时间戳,是正确的。
 
然后试了下获取北交所的历史数据行情:
#-*-coding:gbk-*-
import datetime

code = '838402.BJ'
def init(ContextInfo):
now = datetime.datetime.now()
print(now)
download_history_data(code,"1d","20240105","")

def handlebar(ContextInfo):
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
date = timetag_to_datetime(realtime, "%Y-%m-%d %H:%M:%S")
print(date)
hist = ContextInfo.get_market_data_ex(['close'],[code], period = "1d",count = 1)
print(hist)

代码里面我想用 download_history_data(code,"1d","20240105","") 下载历史数据。
在数据目录里面也能够获取到这个股票的历史数据文件。
 
可是在qmt里面却输出的是个空的dataframe。

20240124133450.png


数据目录下面是有数据的。。
20240124133533.png

感觉是qmt里面的功能还没有完善对北交所股票的支持。
 

华泰matic能在虚拟机运行吗?

李魔佛 发表了文章 • 0 个评论 • 767 次浏览 • 2024-01-05 09:36 • 来自相关话题

答:vmware上不行。登录的时候会直接提示说,matic禁止在虚拟机运行。
 
但matic却可以在hyper X虚拟机上运行。笔者在win11家庭版的hyper x测试过的。
 





 
 
答:vmware上不行。登录的时候会直接提示说,matic禁止在虚拟机运行。
 
但matic却可以在hyper X虚拟机上运行。笔者在win11家庭版的hyper x测试过的。
 

20240105093504.png

 
 

ptrade调试经验分享(坑) 委托成交回调函数

Ptrade李魔佛 发表了文章 • 0 个评论 • 941 次浏览 • 2023-12-22 10:30 • 来自相关话题

特么的在里面的报错了是不会有任何显示!!!!!!
 





 
之前的代码里面,由于少了一个if,导致如果code不在
g.start_buy_sell_queue 
这个集合里面的话,就会报错。(但正常情况下都会有值,但问题就出现在一些特殊情况下)
 
不然你试试在 
on_trade_response
里面直接raise一个Exception出来,日志里也不会有任何显示。
 
切近!! 
on_trade_response 里面做好安全防护!! 最好是有些业务逻辑完成了在里面print一下,以确保是执行到后面的。 查看全部
特么的在里面的报错了是不会有任何显示!!!!!!
 

20231222102356.png

 
之前的代码里面,由于少了一个if,导致如果code不在
g.start_buy_sell_queue 
这个集合里面的话,就会报错。(但正常情况下都会有值,但问题就出现在一些特殊情况下)
 
不然你试试在 
on_trade_response
里面直接raise一个Exception出来,日志里也不会有任何显示。
 
切近!! 
on_trade_response 里面做好安全防护!! 最好是有些业务逻辑完成了在里面print一下,以确保是执行到后面的。

ptrade精确参与集合竞价交易 时间设置问题

Ptrade李魔佛 发表了文章 • 0 个评论 • 1235 次浏览 • 2023-11-16 10:10 • 来自相关话题

最近几次的集合竞价都没有卖出成功。
 
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
 
所以要参与集合竞价,需要设定在9:24分开始,然后不断在一个循环里面,用更小的时间颗粒,比如100ms去监听。
 
等到9:24:59的时间,才去下单。





 





 
具体代码可以参照我的知识星球

 
 
  查看全部
最近几次的集合竞价都没有卖出成功。
 
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
 
所以要参与集合竞价,需要设定在9:24分开始,然后不断在一个循环里面,用更小的时间颗粒,比如100ms去监听。
 
等到9:24:59的时间,才去下单。

20231116100349-v1.png

 

20231116100758-v1.png

 
具体代码可以参照我的知识星球

 
 
 

迅投官网的示例代码真的无眼看。。。

QMT李魔佛 发表了文章 • 0 个评论 • 1126 次浏览 • 2023-11-10 01:17 • 来自相关话题

如果拿去做code review,估计会被喷的体无完肤。
 
变量名,类名用A ,B,C 噗, 没有一点含义,做什么鬼
 class a():
pass
A = a()而且也不符合python风格。。。python类名推荐的大写字母开头,实例化对象用小写字母。
所以退一万步讲,上面的代码正常点的程序员写也应该是这样的。
 class A():
pass
a = A()
  
其实正确的应该class GlobalCls():
pass

g = GlobalCls()
其他地方也是有这个毛病。
把代码喂给GPT,让它来分析一下:
得到如下结果:文件编码声明: #coding:gbk 是指定源文件的编码格式为GBK。在Python 3中,通常使用UTF-8作为文件编码格式,因此可以将该行删除或更改为#coding:utf-8。

类名和函数名: 根据PEP 8命名约定,类名应该使用大写字母开头的驼峰命名法(例如A改为A)。同样,函数名应该使用小写字母开头的小写命名法(例如init改为init,f改为f)。

类和实例: 在代码中定义了一个空类a,但没有给它任何属性或方法。如果不需要这个类,可以将其删除。

缩进和代码格式: Python非常依赖于正确的缩进,以指示代码块的层次结构。请确保代码的缩进是一致的,并使用适当的缩进级别(通常是4个空格)。

代码注释: 代码中有一些注释,但是大部分是被注释掉的。良好的注释可以增加代码的可读性和可维护性,建议在关键部分添加更多有用的注释。

异常处理: 代码中没有包含任何异常处理机制。在实际应用中,建议对可能引发异常的操作进行适当的异常处理,以提高代码的健壮性。
 
然后里面计算涨停是这样的: rise_price = round(full_tick[stock]['lastClose'] *1.2,2) if stock[0] == '3' or stock[:3] == '688' else round(full_tick[stock]['lastClose'] *1.1,2)


用昨收价* 1.2和1.1判断当前是否涨跌停。 首先,没有考虑到ST股,部分ST是5%涨停的。 
其次,是直接用的昨收价,如果当天是分红除权日,昨收价没有做除权处理,得到的涨跌幅也是不准的。
 
当然这个文档最大的问题是,很多示例代码运行是直接报错的!!
 

  查看全部
20231110001.jpg

如果拿去做code review,估计会被喷的体无完肤。
 
变量名,类名用A ,B,C 噗, 没有一点含义,做什么鬼
 
class a():
pass
A = a()
而且也不符合python风格。。。python类名推荐的大写字母开头,实例化对象用小写字母。
所以退一万步讲,上面的代码正常点的程序员写也应该是这样的。
 
class A():
pass
a = A()

  
其实正确的应该
class GlobalCls():
pass

g = GlobalCls()

其他地方也是有这个毛病。
把代码喂给GPT,让它来分析一下:
得到如下结果:
文件编码声明: #coding:gbk 是指定源文件的编码格式为GBK。在Python 3中,通常使用UTF-8作为文件编码格式,因此可以将该行删除或更改为#coding:utf-8。

类名和函数名: 根据PEP 8命名约定,类名应该使用大写字母开头的驼峰命名法(例如A改为A)。同样,函数名应该使用小写字母开头的小写命名法(例如init改为init,f改为f)。

类和实例: 在代码中定义了一个空类a,但没有给它任何属性或方法。如果不需要这个类,可以将其删除。

缩进和代码格式: Python非常依赖于正确的缩进,以指示代码块的层次结构。请确保代码的缩进是一致的,并使用适当的缩进级别(通常是4个空格)。

代码注释: 代码中有一些注释,但是大部分是被注释掉的。良好的注释可以增加代码的可读性和可维护性,建议在关键部分添加更多有用的注释。

异常处理: 代码中没有包含任何异常处理机制。在实际应用中,建议对可能引发异常的操作进行适当的异常处理,以提高代码的健壮性。

 
然后里面计算涨停是这样的:
		rise_price = round(full_tick[stock]['lastClose'] *1.2,2) if stock[0] == '3' or stock[:3] == '688' else round(full_tick[stock]['lastClose'] *1.1,2)


用昨收价* 1.2和1.1判断当前是否涨跌停。 首先,没有考虑到ST股,部分ST是5%涨停的。 
其次,是直接用的昨收价,如果当天是分红除权日,昨收价没有做除权处理,得到的涨跌幅也是不准的。
 
当然这个文档最大的问题是,很多示例代码运行是直接报错的!!
 

 

QMT | Ptrade 量化策略代写服务

李魔佛 发表了文章 • 0 个评论 • 1645 次浏览 • 2023-11-01 10:43 • 来自相关话题

 迅投的QMT和恒生电子的Ptrade, 还有掘金, 量化策略编程, 实盘和回测都行。只要你的需求明确,白纸黑字描述清楚,都可以做。股票,ETF,可转债都行。
 
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
 
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
 
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
 









咨询完,我都感觉我自己以前的报价太低了,呜。
 
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
 
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
 
扫码关注公众号:

  查看全部

Ptrade-QMT_副本.png


 迅投的QMT和恒生电子的Ptrade, 还有掘金, 量化策略编程, 实盘和回测都行。只要你的需求明确,白纸黑字描述清楚,都可以做。股票,ETF,可转债都行。
 
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
 
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
 
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
 
Screenshot_2023_1101_102306_副本.jpg


Screenshot_2023_1101_102257_副本.jpg

咨询完,我都感觉我自己以前的报价太低了,呜。
 
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
 
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
 
扫码关注公众号:

 

QMT获取A股全市场股票代码

QMT李魔佛 发表了文章 • 0 个评论 • 1239 次浏览 • 2023-10-25 15:23 • 来自相关话题

QMT可以通过板块获取A股的全市场股票代码.
 
"沪深A股"
 
完整代码:#-*-coding:gbk-*-
import time
start = False
ACCOUNT = ''

def init(ContextInfo):
now = time.ctime()
print(now)
ContextInfo.run_time("execution","30nSecond","2023-04-14 13:20:00")


def execution(ContextInfo):
data = ContextInfo.get_stock_list_in_sector('沪深A股')
print(len(data))

def handlebar(ContextInfo):
pass
当前共有5047只股票【2023-10-25 15:18:45.533】 start trading mode
【2023-10-25 15:18:45.533】 Wed Oct 25 15:18:45 2023

【2023-10-25 15:18:45.533】 5074
['000001.SZ', '000002.SZ', '000004.SZ', '000005.SZ', '000006.SZ', '000007.SZ', '000008.SZ', '000009.SZ', '000010.SZ', '000011.SZ', '000012.SZ', '000014.SZ', '000016.SZ', '000017.SZ', '000019.SZ', '000020.SZ', '000021.SZ', '000023.SZ', '000025.SZ', '000026.SZ', '000027.SZ', '000028.SZ', '000029.SZ', '000030.SZ', '000031.SZ', '000032.SZ', '000034.SZ', '000035.SZ', '000036.SZ', '000037.SZ', '000039.SZ', '000040.SZ', '000042.SZ', '000045.SZ', '000046.SZ', '000048.SZ', '000049.SZ', '000050.SZ', '000055.SZ', '000056.SZ', '000058.SZ', '000059.SZ', '000060.SZ', '000061.SZ', '000062.SZ', '000063.SZ', '000065.SZ', '000066.SZ', '000068.SZ', '000069.SZ', '000070.SZ', '000078.SZ', '000088.SZ', '000089.SZ', '000090.SZ', '000096.SZ', '000099.SZ', '000100.SZ', '000151.SZ', '000153.SZ', '000155.SZ', '000156.SZ', '000157.SZ', '000158.SZ', '000159.SZ', '000166.SZ', '000301.SZ', '000333.SZ', '000338.SZ', '000400.SZ', '000401.SZ', '000402.SZ', '000403.SZ', '000404.SZ', '000407.SZ', '000408.SZ', '000409.SZ', '000410.SZ', '000411.SZ', '000413.SZ', '000415.SZ', '000416.SZ', '000417.SZ', '000419.SZ', '000420.SZ', '000421.SZ', '000422.SZ', '000423.SZ', '000425.SZ', '000426.SZ',省略若干...
 
点击查看大图




 
是否遇到QMT或Ptrade的问题, 无从入手? 或者咨询无门 ?
来加入 知识星球 , 获取专业的技术解答, 量化实盘代码, 技术交流群

  查看全部
QMT可以通过板块获取A股的全市场股票代码.
 
"沪深A股"
 
完整代码:
#-*-coding:gbk-*-
import time
start = False
ACCOUNT = ''

def init(ContextInfo):
now = time.ctime()
print(now)
ContextInfo.run_time("execution","30nSecond","2023-04-14 13:20:00")


def execution(ContextInfo):
data = ContextInfo.get_stock_list_in_sector('沪深A股')
print(len(data))

def handlebar(ContextInfo):
pass

当前共有5047只股票
【2023-10-25 15:18:45.533】  start trading mode
【2023-10-25 15:18:45.533】 Wed Oct 25 15:18:45 2023

【2023-10-25 15:18:45.533】 5074
['000001.SZ', '000002.SZ', '000004.SZ', '000005.SZ', '000006.SZ', '000007.SZ', '000008.SZ', '000009.SZ', '000010.SZ', '000011.SZ', '000012.SZ', '000014.SZ', '000016.SZ', '000017.SZ', '000019.SZ', '000020.SZ', '000021.SZ', '000023.SZ', '000025.SZ', '000026.SZ', '000027.SZ', '000028.SZ', '000029.SZ', '000030.SZ', '000031.SZ', '000032.SZ', '000034.SZ', '000035.SZ', '000036.SZ', '000037.SZ', '000039.SZ', '000040.SZ', '000042.SZ', '000045.SZ', '000046.SZ', '000048.SZ', '000049.SZ', '000050.SZ', '000055.SZ', '000056.SZ', '000058.SZ', '000059.SZ', '000060.SZ', '000061.SZ', '000062.SZ', '000063.SZ', '000065.SZ', '000066.SZ', '000068.SZ', '000069.SZ', '000070.SZ', '000078.SZ', '000088.SZ', '000089.SZ', '000090.SZ', '000096.SZ', '000099.SZ', '000100.SZ', '000151.SZ', '000153.SZ', '000155.SZ', '000156.SZ', '000157.SZ', '000158.SZ', '000159.SZ', '000166.SZ', '000301.SZ', '000333.SZ', '000338.SZ', '000400.SZ', '000401.SZ', '000402.SZ', '000403.SZ', '000404.SZ', '000407.SZ', '000408.SZ', '000409.SZ', '000410.SZ', '000411.SZ', '000413.SZ', '000415.SZ', '000416.SZ', '000417.SZ', '000419.SZ', '000420.SZ', '000421.SZ', '000422.SZ', '000423.SZ', '000425.SZ', '000426.SZ',
省略若干...
 
点击查看大图
20231025152005.png

 
是否遇到QMT或Ptrade的问题, 无从入手? 或者咨询无门 ?
来加入 知识星球 , 获取专业的技术解答, 量化实盘代码, 技术交流群