通知设置 新通知
LOF基金出现大量套利机会,微信发送套利提示机会
李魔佛 发表了文章 • 0 个评论 • 48 次浏览 • 2024-10-05 17:54
对于踏空的投资来说,简直比满仓套牢还难受。
虽然行情火爆,但头脑依然要保持清醒,不要看到什么热门就一股脑冲进去。
错误的方式,让你赚到了大钱,实际会后患无穷。
“有勇敢的飞行员,有年老的飞行员,但鲜有勇敢的年老飞行员"
行情爆发,大部分人连指数都追不上,所以索性直接打板指数。以至于各种指数10CM,甚至20CM。
实际指数的成分股并没有出现全部涨停那么夸张。
所以这时出现不少溢价的LOF基金,基金价格高于其净值。于是就出现了套利的机会。
溢价率越高,其安全垫也就越高。对于当前空仓或者轻仓的投资者而言,是一个不错的介入机会。(具体套利操作就是,场内净值申购,T+2或者T+3到账后,场内现价卖出)
这里笔者根据之前的LOF监控程序,程序自动获取限购-溢价LOF基金套利,并推送到微信消息,获取了目前溢价率大于5%的LOF基金,然后按照其成交量从大到小排序,得到下表:
成交量越大的,说明该LOF越活跃,这样就不至于在套利大军进场的时候,承接不住,被砸到跌停出不去。
目前成交量最大的是中概互联LOF164906,成交量1.9亿。成交量最少的是鼎弘LOF167003,成交量只有4万块不到,即使有14%的溢价率的肉垫,但容量太少,随便一个大户砸下来就跌停了。
所以这里也建议要介入额投资者,不仅仅只看溢价率,同时也要关注成交量。
同时也要注意申购状态那一列,积极配置FOF和原油LOF易方达 目前处于暂停申购状态,也就是当前是无法进行套利的。
而恒生LOF 是限购状态,限购5000元,因为港股假期猛涨了一波,所以大概率这个基金周二开盘会直接顶住涨停的。该基金是深市基金,可以6+1拖拉机拉满。申购7户,35000元。
结合之前的程序,LOF溢价率监控+微信推送,可以做到收盘前推送数据:
当然你用飞书,钉钉也行。如果要用微信,早期开通的api还能继续用,新开的就需要备案的服务器了,手续就麻烦一点。
广告时间:需要低佣免5开户的可以公众号菜单联系,支持Ptrade,QMT,miniQMT,套利拖拉机。
查看全部
对于踏空的投资来说,简直比满仓套牢还难受。
虽然行情火爆,但头脑依然要保持清醒,不要看到什么热门就一股脑冲进去。
错误的方式,让你赚到了大钱,实际会后患无穷。
“有勇敢的飞行员,有年老的飞行员,但鲜有勇敢的年老飞行员"
行情爆发,大部分人连指数都追不上,所以索性直接打板指数。以至于各种指数10CM,甚至20CM。
实际指数的成分股并没有出现全部涨停那么夸张。
所以这时出现不少溢价的LOF基金,基金价格高于其净值。于是就出现了套利的机会。
溢价率越高,其安全垫也就越高。对于当前空仓或者轻仓的投资者而言,是一个不错的介入机会。(具体套利操作就是,场内净值申购,T+2或者T+3到账后,场内现价卖出)
这里笔者根据之前的LOF监控程序,程序自动获取限购-溢价LOF基金套利,并推送到微信消息,获取了目前溢价率大于5%的LOF基金,然后按照其成交量从大到小排序,得到下表:
成交量越大的,说明该LOF越活跃,这样就不至于在套利大军进场的时候,承接不住,被砸到跌停出不去。
目前成交量最大的是中概互联LOF164906,成交量1.9亿。成交量最少的是鼎弘LOF167003,成交量只有4万块不到,即使有14%的溢价率的肉垫,但容量太少,随便一个大户砸下来就跌停了。
所以这里也建议要介入额投资者,不仅仅只看溢价率,同时也要关注成交量。
同时也要注意申购状态那一列,积极配置FOF和原油LOF易方达 目前处于暂停申购状态,也就是当前是无法进行套利的。
而恒生LOF 是限购状态,限购5000元,因为港股假期猛涨了一波,所以大概率这个基金周二开盘会直接顶住涨停的。该基金是深市基金,可以6+1拖拉机拉满。申购7户,35000元。
结合之前的程序,LOF溢价率监控+微信推送,可以做到收盘前推送数据:
当然你用飞书,钉钉也行。如果要用微信,早期开通的api还能继续用,新开的就需要备案的服务器了,手续就麻烦一点。
广告时间:需要低佣免5开户的可以公众号菜单联系,支持Ptrade,QMT,miniQMT,套利拖拉机。
QMT获取不到行情,一般是什么原因?或者获取行情有中断的情况
QMT • 李魔佛 发表了文章 • 0 个评论 • 114 次浏览 • 2024-09-29 10:27
或者你获取的5档tick行情,但是你的行情菜单那里,选择的是 最新价,这样你也是无法获取到 5档tick数据的。
然后还有一个问题,如果你用get_market_data 或者get_market_data_ex 这个函数,获取的股票数量很多(比如全市场的股票),那么第一次的启动数据会非常的慢,并且你的内存消耗非常大,整个QMT像死机了一样。
如何解决? 下回分解
查看全部
Ptrade回测模式下获取实时的分钟数据:只能使用handle_data,数据不能用get_snapshot
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 212 次浏览 • 2024-09-21 17:32
发现有点蛋疼,记录一下。
因为回测模式下,不能使用run_interval 函数;
而run_daily模式,只能在固定时间运行,无法分钟级别。
所以只能使用 handle_data
而在handle_data 里面获取当前的分钟价格数据,也无法使用 get_snapshot ,get_gear_price,函数。
所以只能使用handle_data(Context,data) 里面的data里。
而handle_data 里面的data数据,使用方法如下:
import datetime
target_list = [
'600000.SS',
'000333.SZ'
]
def execution(context, data):
now = context.current_dt.strftime('%H:%M')
for code in target_list:
tick_info = data[code]
price = tick_info['price']
print('now: {} code : {} price:{}'.format(now,code ,price))
# 标准
def initialize(context):
log.info("公众号:可转债量化分析 ---- start ----")
def handle_data(context, data):
execution(context, data)
获取数据结果:2024-09-20 14:42:00 - INFO - now: 14:42 code : 000333.SZ price:66.22
2024-09-20 14:43:00 - INFO - now: 14:43 code : 000333.SZ price:66.26
2024-09-20 14:44:00 - INFO - now: 14:44 code : 000333.SZ price:66.19
2024-09-20 14:45:00 - INFO - now: 14:45 code : 000333.SZ price:66.2
2024-09-20 14:46:00 - INFO - now: 14:46 code : 000333.SZ price:66.19
2024-09-20 14:47:00 - INFO - now: 14:47 code : 000333.SZ price:66.18
2024-09-20 14:48:00 - INFO - now: 14:48 code : 000333.SZ price:66.14
2024-09-20 14:49:00 - INFO - now: 14:49 code : 000333.SZ price:66.25
2024-09-20 14:50:00 - INFO - now: 14:50 code : 000333.SZ price:66.19
2024-09-20 14:51:00 - INFO - now: 14:51 code : 000333.SZ price:66.18
2024-09-20 14:52:00 - INFO - now: 14:52 code : 000333.SZ price:66.19
2024-09-20 14:53:00 - INFO - now: 14:53 code : 000333.SZ price:66.2
2024-09-20 14:54:00 - INFO - now: 14:54 code : 000333.SZ price:66.19
2024-09-20 14:55:00 - INFO - now: 14:55 code : 000333.SZ price:66.25
2024-09-20 14:56:00 - INFO - now: 14:56 code : 000333.SZ price:66.27
2024-09-20 14:57:00 - INFO - now: 14:57 code : 000333.SZ price:66.28
2024-09-20 14:58:00 - INFO - now: 14:58 code : 000333.SZ price:66.28
2024-09-20 14:59:00 - INFO - now: 14:59 code : 000333.SZ price:66.28
2024-09-20 15:00:00 - INFO - now: 15:00 code : 000333.SZ price:66.06
用同花顺,对了一下结果,是满足的了。
查看全部
发现有点蛋疼,记录一下。
因为回测模式下,不能使用run_interval 函数;
而run_daily模式,只能在固定时间运行,无法分钟级别。
所以只能使用 handle_data
而在handle_data 里面获取当前的分钟价格数据,也无法使用 get_snapshot ,get_gear_price,函数。
所以只能使用handle_data(Context,data) 里面的data里。
而handle_data 里面的data数据,使用方法如下:
import datetime
target_list = [
'600000.SS',
'000333.SZ'
]
def execution(context, data):
now = context.current_dt.strftime('%H:%M')
for code in target_list:
tick_info = data[code]
price = tick_info['price']
print('now: {} code : {} price:{}'.format(now,code ,price))
# 标准
def initialize(context):
log.info("公众号:可转债量化分析 ---- start ----")
def handle_data(context, data):
execution(context, data)
获取数据结果:
2024-09-20 14:42:00 - INFO - now: 14:42 code : 000333.SZ price:66.22
2024-09-20 14:43:00 - INFO - now: 14:43 code : 000333.SZ price:66.26
2024-09-20 14:44:00 - INFO - now: 14:44 code : 000333.SZ price:66.19
2024-09-20 14:45:00 - INFO - now: 14:45 code : 000333.SZ price:66.2
2024-09-20 14:46:00 - INFO - now: 14:46 code : 000333.SZ price:66.19
2024-09-20 14:47:00 - INFO - now: 14:47 code : 000333.SZ price:66.18
2024-09-20 14:48:00 - INFO - now: 14:48 code : 000333.SZ price:66.14
2024-09-20 14:49:00 - INFO - now: 14:49 code : 000333.SZ price:66.25
2024-09-20 14:50:00 - INFO - now: 14:50 code : 000333.SZ price:66.19
2024-09-20 14:51:00 - INFO - now: 14:51 code : 000333.SZ price:66.18
2024-09-20 14:52:00 - INFO - now: 14:52 code : 000333.SZ price:66.19
2024-09-20 14:53:00 - INFO - now: 14:53 code : 000333.SZ price:66.2
2024-09-20 14:54:00 - INFO - now: 14:54 code : 000333.SZ price:66.19
2024-09-20 14:55:00 - INFO - now: 14:55 code : 000333.SZ price:66.25
2024-09-20 14:56:00 - INFO - now: 14:56 code : 000333.SZ price:66.27
2024-09-20 14:57:00 - INFO - now: 14:57 code : 000333.SZ price:66.28
2024-09-20 14:58:00 - INFO - now: 14:58 code : 000333.SZ price:66.28
2024-09-20 14:59:00 - INFO - now: 14:59 code : 000333.SZ price:66.28
2024-09-20 15:00:00 - INFO - now: 15:00 code : 000333.SZ price:66.06
用同花顺,对了一下结果,是满足的了。
QMT的handlebar设置成一分钟周期的时候,运行是3秒一次的
QMT • 李魔佛 发表了文章 • 0 个评论 • 246 次浏览 • 2024-09-13 11:46
刚好有个策略是一分钟周期运行的,所以就用了handle驱动。
结果发现,经常查询重复买入。
调试后发现,原来这个handlebar是3m触发一次的。
如果要一分钟运行一次,还是用
ContextInfo.run_time("execution", INTERVAL_STRING, running_time)
INTERVAL_STRING 用1分钟表示。
示例代码:
一分钟打印当前时间:
# -*-coding:gbk-*-
# 作者公众号:可转债量化分析
import datetime
import json
import redis
####### 以下为固定配置,请勿随意修改 ##########
# 注意:程序需要在9:30前启动
START_TIME = '09:30' # 启动时间,可以修改为开盘任意时间9:30-14:57
STOCK_ACCOUNT = '' # 股票账户
INTERVAL_SECOND = 60 # 交易间隔
INTERVAL_STRING = "{}nSecond".format(INTERVAL_SECOND)
def today_date():
return datetime.datetime.now().strftime('%Y%m%d')
def init(ContextInfo):
now = datetime.datetime.now()
print('策略初始化 {}'.format(now))
now = datetime.datetime.now()
running_time = '{} {}'.format(today_date(), START_TIME)
print('策略初始化 {} , 程序启动时间 {}'.format(now, START_TIME))
ContextInfo.run_time("execution", INTERVAL_STRING, running_time)
def handlebar(ContextInfo):
pass
def execution(ContextInfo):
if not ContextInfo.is_last_bar():
return
now = datetime.datetime.now()
print(now)
公众号: 查看全部
刚好有个策略是一分钟周期运行的,所以就用了handle驱动。
结果发现,经常查询重复买入。
调试后发现,原来这个handlebar是3m触发一次的。
如果要一分钟运行一次,还是用
ContextInfo.run_time("execution", INTERVAL_STRING, running_time)
INTERVAL_STRING 用1分钟表示。
示例代码:
一分钟打印当前时间:
# -*-coding:gbk-*-
# 作者公众号:可转债量化分析
import datetime
import json
import redis
####### 以下为固定配置,请勿随意修改 ##########
# 注意:程序需要在9:30前启动
START_TIME = '09:30' # 启动时间,可以修改为开盘任意时间9:30-14:57
STOCK_ACCOUNT = '' # 股票账户
INTERVAL_SECOND = 60 # 交易间隔
INTERVAL_STRING = "{}nSecond".format(INTERVAL_SECOND)
def today_date():
return datetime.datetime.now().strftime('%Y%m%d')
def init(ContextInfo):
now = datetime.datetime.now()
print('策略初始化 {}'.format(now))
now = datetime.datetime.now()
running_time = '{} {}'.format(today_date(), START_TIME)
print('策略初始化 {} , 程序启动时间 {}'.format(now, START_TIME))
ContextInfo.run_time("execution", INTERVAL_STRING, running_time)
def handlebar(ContextInfo):
pass
def execution(ContextInfo):
if not ContextInfo.is_last_bar():
return
now = datetime.datetime.now()
print(now)
公众号:
QMT/iQuant居然禁止redis获取股票行情数据,如何破解
QMT • 李魔佛 发表了文章 • 0 个评论 • 386 次浏览 • 2024-09-10 11:26
因为QMT没有转债的规模,而国信iquant本身又把requests 库给封禁了,它无法通过requests 获取任何外部数据,比如访问东财,tushare都会提示访问超时。(后面发现它修改了requests的源码)
于是发现iquant的redis是内置库,不需要pip安装,所以第一时间就想到使用redis获取转债数据。
简单测试了一下,redis是可以获取数据的。比如随便丢一个字符到redis,然后QMT可以获取到这个字符数据
于是就把原来的策略里,使用requests 调用API的部分,改成redis。
可是运行后发现报错:
2024-09-10 10:05:19,851 [INFO] [0x00000e24] [msg service] msg: 0C:\iquant\python\新建策略文件.py_SH00030021
DataError:Sensitive Data Detected, Forbidden!
报错信息说的很明显,敏感信息检测到,禁止!
居然对redis的数据进行检验,很明显这部分是QMT对redis的源码进行了修改。
于是根据报错的提示,找到 目录:
D:\tool\gjzq_qmt_simulation\bin.x64\Lib\site-packages\redis,下面的client.py
找到对应的行:
的确有一个check_response 的函数用于检测 redis的内容,看正则表达式和变量命名(search_stock),类似股票代码的数据传输被阻止了,检测到之后直接raise Error,程序会停止的。
解决办法,也很简单,直接把这一段 代码删除就好了。
然后需要重启你的QMT,不然修改的代码不会生效。
然后重新运行的你的策略,发现一起正常了。
需要开通QMT和代写量化策略,可以关注公众号: 查看全部
因为QMT没有转债的规模,而国信iquant本身又把requests 库给封禁了,它无法通过requests 获取任何外部数据,比如访问东财,tushare都会提示访问超时。(后面发现它修改了requests的源码)
于是发现iquant的redis是内置库,不需要pip安装,所以第一时间就想到使用redis获取转债数据。
简单测试了一下,redis是可以获取数据的。比如随便丢一个字符到redis,然后QMT可以获取到这个字符数据
于是就把原来的策略里,使用requests 调用API的部分,改成redis。
可是运行后发现报错:
2024-09-10 10:05:19,851 [INFO] [0x00000e24] [msg service] msg: 0C:\iquant\python\新建策略文件.py_SH00030021
DataError:Sensitive Data Detected, Forbidden!
报错信息说的很明显,敏感信息检测到,禁止!
居然对redis的数据进行检验,很明显这部分是QMT对redis的源码进行了修改。
于是根据报错的提示,找到 目录:
D:\tool\gjzq_qmt_simulation\bin.x64\Lib\site-packages\redis,下面的client.py
找到对应的行:
的确有一个check_response 的函数用于检测 redis的内容,看正则表达式和变量命名(search_stock),类似股票代码的数据传输被阻止了,检测到之后直接raise Error,程序会停止的。
解决办法,也很简单,直接把这一段 代码删除就好了。
然后需要重启你的QMT,不然修改的代码不会生效。
然后重新运行的你的策略,发现一起正常了。
需要开通QMT和代写量化策略,可以关注公众号:
国信iquant requests 爬虫 获取数据 还有使用 tushare,akshare 无法连接,提示超时
QMT • 李魔佛 发表了文章 • 0 个评论 • 395 次浏览 • 2024-08-28 14:29
#encoding:gbk
import requests
def get_baidu():
url = 'https://www.baidu.com'
req = requests.get(url,headers={'User-Agent':'Mozilla/5.0'})
print(req.text)
def init(ContextInfo):
get_baidu()
def handlebar(ContextInfo):
pass
会报错,同时访问baidu.com 超时:
明显是国信的iquant内部设置了proxy,导致request出去的时候走了proxy。
所以连baidu都访问不了。
而tushare,akshare底层是周的爬虫 (requests), 所以对于iquant,底层走http requests的库,或者获取数据的手段是失效了的。
不过也有其他的手段可以实现获取外部数据。
笔者亲测了redis可以访问外部的redis数据库,为啥用redis,因为iquant没有内置pymysql,需要自己安装,客户也不懂怎么安装,(到iquant的安装文件路径下的python 包路径下,运行 pip install pymysq)
而iquant内置了redis 的库,所以可以直接import redis
redis测试代码:
def base_usage():
print('start')
r = RedisCls()
data = {'name': 'zhangsan', 'age': 18}
key = 'test_key'
r.push(key, json.dumps(data))
print('push')
print(r.delete('key')) # reutrn 1 if delete success, else return 0
start_time = time.time()
ret_data = r.pop(key)
end_time = time.time()
print('cost time: ', end_time - start_time)
print(ret_data)
base_usage()
上面的代码是正常运行,不报错,就说明正常的了。
PS:
r = RedisCls() 只是封装了
r = redis.Redis 连接的ip和端口,密码 而已。
按照网上的redis连接教程使用就好了。
查看全部
#encoding:gbk
import requests
def get_baidu():
url = 'https://www.baidu.com'
req = requests.get(url,headers={'User-Agent':'Mozilla/5.0'})
print(req.text)
def init(ContextInfo):
get_baidu()
def handlebar(ContextInfo):
pass
会报错,同时访问baidu.com 超时:
明显是国信的iquant内部设置了proxy,导致request出去的时候走了proxy。
所以连baidu都访问不了。
而tushare,akshare底层是周的爬虫 (requests), 所以对于iquant,底层走http requests的库,或者获取数据的手段是失效了的。
不过也有其他的手段可以实现获取外部数据。
笔者亲测了redis可以访问外部的redis数据库,为啥用redis,因为iquant没有内置pymysql,需要自己安装,客户也不懂怎么安装,(到iquant的安装文件路径下的python 包路径下,运行 pip install pymysq)
而iquant内置了redis 的库,所以可以直接import redis
redis测试代码:
def base_usage():
print('start')
r = RedisCls()
data = {'name': 'zhangsan', 'age': 18}
key = 'test_key'
r.push(key, json.dumps(data))
print('push')
print(r.delete('key')) # reutrn 1 if delete success, else return 0
start_time = time.time()
ret_data = r.pop(key)
end_time = time.time()
print('cost time: ', end_time - start_time)
print(ret_data)
base_usage()
上面的代码是正常运行,不报错,就说明正常的了。
PS:
r = RedisCls() 只是封装了
r = redis.Redis 连接的ip和端口,密码 而已。
按照网上的redis连接教程使用就好了。
QMT如何获取持仓成本 盈亏比例
QMT • 李魔佛 发表了文章 • 0 个评论 • 439 次浏览 • 2024-08-25 07:50
那么QMT有没有内置的可以获取持仓成本的函数呢?
position 持仓对象 里面有一个字段:
m_dOpenPrice: 持仓成本
可以用来获取当前的持仓成本:
具体代码如下:
# encoding:gbk
ACCOUNT = 'xxxxxxx' # 填入你的QMT账户ID, 如果没有,可以联系我开通 QMT权限
def init(ContextInfo):
# hs300成分股中sh和sz市场各自流通市值最大的前3只股票
pass
def handlebar(ContextInfo):
# 计算当前主图的cci
position_info = get_trade_detail_data(ACCOUNT, 'stock', 'position')
for i in position_info:
print('股票', i.m_strInstrumentID, '持仓数',
i.m_nVolume, '持有成本', round(i.m_dOpenPrice, 2),
'持仓盈亏', round(i.m_dPositionProfit, 2),
'持仓盈亏比例', round(i.m_dProfitRate*100, 2)
)
得到的输出结果:
扫码免费开通QMT:
查看全部
那么QMT有没有内置的可以获取持仓成本的函数呢?
position 持仓对象 里面有一个字段:
m_dOpenPrice: 持仓成本
可以用来获取当前的持仓成本:
具体代码如下:
# encoding:gbk
ACCOUNT = 'xxxxxxx' # 填入你的QMT账户ID, 如果没有,可以联系我开通 QMT权限
def init(ContextInfo):
# hs300成分股中sh和sz市场各自流通市值最大的前3只股票
pass
def handlebar(ContextInfo):
# 计算当前主图的cci
position_info = get_trade_detail_data(ACCOUNT, 'stock', 'position')
for i in position_info:
print('股票', i.m_strInstrumentID, '持仓数',
i.m_nVolume, '持有成本', round(i.m_dOpenPrice, 2),
'持仓盈亏', round(i.m_dPositionProfit, 2),
'持仓盈亏比例', round(i.m_dProfitRate*100, 2)
)
得到的输出结果:
扫码免费开通QMT:
python Ptrade获取热门板块,连板股票 python代码
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 400 次浏览 • 2024-08-23 16:57
Ptrade API文档:https://ptradeapi.com/#get_sort_msg
get_sort_msg – 获取板块、行业的涨幅排名
get_sort_msg(sort_type_grp=None, sort_field_name=None, sort_type=1, data_count=100)
接口说明
该接口用于获取板块、行业的涨幅排名。
参数 sort_type_grp: 板块或行业的代码(list[str]/str);
(暂时只支持XBHS.DY地域、XBHS.GN概念、XBHS.ZJHHY证监会行业、XBHS.ZS指数、XBHS.HY行业等)
示例代码:按概念板块涨幅倒序排名
import datetime
START_TIME = (datetime.datetime.now() + datetime.timedelta(minutes=1)).strftime('%H:%M')
def execution(context):
#获取XBHS.GN的概念排名信息
sort_data = get_sort_msg(sort_type_grp='XBHS.GN', sort_field_name='px_change_rate', sort_type=1, data_count=100)
for data in sort_data:
log.info('板块: {} '.format(data['prod_name']))
for sub_stock in data['rise_first_grp']:
log.info('{} 涨幅 :{}'.format(sub_stock['prod_name'],sub_stock['px_change_rate']))
log.info('\n')
def initialize(context):
# 初始化策略
run_daily(context, execution, time=START_TIME) # 扫描
log.info("公众号:可转债量化分析\n")
def handle_data(context, data):
pass
上面代码在ptrade启动后一分钟拿到结果。不限制要求开盘时间的。其实Ptrade可以在24小时任意时刻启动。
get_sort_msg 返回的数据结构体如下:
具体字段的含义:
prod_code: 行业代码(str:str);
prod_name: 行业名称(str:str);
hq_type_code: 行业板块代码(str:str);
time_stamp: 时间戳毫秒级(str:int);
trade_mins: 交易分钟数(str:int);
trade_status: 交易状态(str:str);
preclose_px: 昨日收盘价(str:float);
open_px: 今日开盘价(str:float);
last_px: 最新价(str:float);
high_px: 最高价(str:float);
low_px: 最低价(str:float);
wavg_px: 加权平均价(str:float);
business_amount: 总成交量(str:int);
business_balance: 总成交额(str:int);
px_change: 涨跌额(str:float);
amplitude: 振幅(str:int);
px_change_rate: 涨跌幅(str:float);
circulation_amount: 流通股本(str:int);
total_shares: 总股本(str:int);
market_value: 市值(str:int);
circulation_value: 流通市值(str:int);
vol_ratio: 量比(str:float);
shares_per_hand: 每手股数(str:int);
rise_count: 上涨家数(str:int);
fall_count: 下跌家数(str:int);
member_count: 成员个数(str:int);
rise_first_grp: 领涨股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
fall_first_grp: 领跌股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
这个返回数据是实时的,可以用来选股,选择热门股,热门板块,涨停板块,昨日涨停,昨日连板板块。
比如上面运行结果里就有 昨日连板的板块个股,有9个,在rise_first_grp 字段里面:
需要开通Ptrade的读者朋友可以后天联系哦,提供不同券商ptrade,低门槛,低费率,还有技术支持群!
查看全部
Ptrade API文档:https://ptradeapi.com/#get_sort_msg
get_sort_msg – 获取板块、行业的涨幅排名
get_sort_msg(sort_type_grp=None, sort_field_name=None, sort_type=1, data_count=100)
接口说明
该接口用于获取板块、行业的涨幅排名。
参数 sort_type_grp: 板块或行业的代码(list[str]/str);
(暂时只支持XBHS.DY地域、XBHS.GN概念、XBHS.ZJHHY证监会行业、XBHS.ZS指数、XBHS.HY行业等)
示例代码:按概念板块涨幅倒序排名
import datetime
START_TIME = (datetime.datetime.now() + datetime.timedelta(minutes=1)).strftime('%H:%M')
def execution(context):
#获取XBHS.GN的概念排名信息
sort_data = get_sort_msg(sort_type_grp='XBHS.GN', sort_field_name='px_change_rate', sort_type=1, data_count=100)
for data in sort_data:
log.info('板块: {} '.format(data['prod_name']))
for sub_stock in data['rise_first_grp']:
log.info('{} 涨幅 :{}'.format(sub_stock['prod_name'],sub_stock['px_change_rate']))
log.info('\n')
def initialize(context):
# 初始化策略
run_daily(context, execution, time=START_TIME) # 扫描
log.info("公众号:可转债量化分析\n")
def handle_data(context, data):
pass
上面代码在ptrade启动后一分钟拿到结果。不限制要求开盘时间的。其实Ptrade可以在24小时任意时刻启动。
get_sort_msg 返回的数据结构体如下:
具体字段的含义:
prod_code: 行业代码(str:str);
prod_name: 行业名称(str:str);
hq_type_code: 行业板块代码(str:str);
time_stamp: 时间戳毫秒级(str:int);
trade_mins: 交易分钟数(str:int);
trade_status: 交易状态(str:str);
preclose_px: 昨日收盘价(str:float);
open_px: 今日开盘价(str:float);
last_px: 最新价(str:float);
high_px: 最高价(str:float);
low_px: 最低价(str:float);
wavg_px: 加权平均价(str:float);
business_amount: 总成交量(str:int);
business_balance: 总成交额(str:int);
px_change: 涨跌额(str:float);
amplitude: 振幅(str:int);
px_change_rate: 涨跌幅(str:float);
circulation_amount: 流通股本(str:int);
total_shares: 总股本(str:int);
market_value: 市值(str:int);
circulation_value: 流通市值(str:int);
vol_ratio: 量比(str:float);
shares_per_hand: 每手股数(str:int);
rise_count: 上涨家数(str:int);
fall_count: 下跌家数(str:int);
member_count: 成员个数(str:int);
rise_first_grp: 领涨股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
fall_first_grp: 领跌股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
这个返回数据是实时的,可以用来选股,选择热门股,热门板块,涨停板块,昨日涨停,昨日连板板块。
比如上面运行结果里就有 昨日连板的板块个股,有9个,在rise_first_grp 字段里面:
需要开通Ptrade的读者朋友可以后天联系哦,提供不同券商ptrade,低门槛,低费率,还有技术支持群!
【保姆教程】使用ptrade做一个持仓监控提醒软件 (二)
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 626 次浏览 • 2024-08-08 14:01
主要框架如下:
盘前我们先去读取数据库的数据:
格式很简单,就记录了代码和名字:
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
def initialize(context):
# 初始化策略
engine = DBSelector().get_engine()
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
df['code']=df['code'].astype(str)
result = {}
for index, row in df.iterrows():
code = add_code_postfix(row['code'])
result[code] = {'name': row['name'], 'source': row['source']}
g.holding_stock_dict = result
g.holding_stock_list = list(result.keys())
g.__cache = Cache()
run_interval(context, execution, seconds=INTERVAL) # 扫描
def handle_data(context, data):
pass
def tick_data(context, data):
pass
def before_trading_start(context, data):
'''
盘前
'''
if DEBUG:
log.info('盘前运行开始', str(context.blotter.current_dt))
def after_trading_end(context, data):
'''
盘后
'''
if DEBUG:
log.info('盘后时间 ', str(context.blotter.current_dt))
然后主要部分在 execution 这个监控函数这里。
def execution(context):
tick_info = get_snapshot(g.holding_stock_list)
for code, tick in tick_info.items():
px_change_rate = tick['px_change_rate']
if px_change_rate > abs(HIT_TARGET):
if g.__cache.check(code):
# 通知
name = g.holding_stock_dict.get(code)['name']
source = g.holding_stock_dict.get(code)['source']
msg = '{}-{} 涨幅-{},{}'.format(code,
name, px_change_rate, source)
send_message_via_wechat(msg)
send_message_via_wechat 这个函数是发送微信消息的。
然后基本完成了整体的代码编写,里面一些自定义的函数为了判断 下一次通知要等待多久。
因为不能因为同一个股票满足条件了,然后每隔3秒发一次微信消息。你手机会一直滴滴滴地响的。
而且很容易把其他刚出现的提示给覆盖了。
【保姆教程】使用ptrade做一个持仓监控提醒软件 (一)
查看全部
主要框架如下:
盘前我们先去读取数据库的数据:
格式很简单,就记录了代码和名字:
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
def initialize(context):
# 初始化策略
engine = DBSelector().get_engine()
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
df['code']=df['code'].astype(str)
result = {}
for index, row in df.iterrows():
code = add_code_postfix(row['code'])
result[code] = {'name': row['name'], 'source': row['source']}
g.holding_stock_dict = result
g.holding_stock_list = list(result.keys())
g.__cache = Cache()
run_interval(context, execution, seconds=INTERVAL) # 扫描
def handle_data(context, data):
pass
def tick_data(context, data):
pass
def before_trading_start(context, data):
'''
盘前
'''
if DEBUG:
log.info('盘前运行开始', str(context.blotter.current_dt))
def after_trading_end(context, data):
'''
盘后
'''
if DEBUG:
log.info('盘后时间 ', str(context.blotter.current_dt))
然后主要部分在 execution 这个监控函数这里。
def execution(context):
tick_info = get_snapshot(g.holding_stock_list)
for code, tick in tick_info.items():
px_change_rate = tick['px_change_rate']
if px_change_rate > abs(HIT_TARGET):
if g.__cache.check(code):
# 通知
name = g.holding_stock_dict.get(code)['name']
source = g.holding_stock_dict.get(code)['source']
msg = '{}-{} 涨幅-{},{}'.format(code,
name, px_change_rate, source)
send_message_via_wechat(msg)
send_message_via_wechat 这个函数是发送微信消息的。
然后基本完成了整体的代码编写,里面一些自定义的函数为了判断 下一次通知要等待多久。
因为不能因为同一个股票满足条件了,然后每隔3秒发一次微信消息。你手机会一直滴滴滴地响的。
而且很容易把其他刚出现的提示给覆盖了。
【保姆教程】使用ptrade做一个持仓监控提醒软件 (一)
【保姆教程】使用ptrade做一个持仓监控提醒软件 (一)
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 629 次浏览 • 2024-08-07 10:23
因为有多个券商,比如银河,华宝,国金,国盛等。 而且也有家人的账户,可能一个银河就有5-6个账户。
所以如果持仓比较多的话,没有时间管得过来。 设置条件单比较繁琐,也不一定能管得过来。
要求:
把所有的持仓股Excel导出,输入的数据库(这里选择mysql),然后Ptrade读取了股票池,每隔3s扫描一次行情,如果遇到大涨或者大跌的个股,转债,ETF,就发送微信消息提醒(涨幅/跌幅大于7%)
这个是某个客户的简单需求。
后面就按照上面的需求做一个客户端,除了可以录入上述资料,还能提供web服务,输入,删除持仓股,做到实时更新。
最后提醒效果如下:
国金QMT的字样,用来区分我这个标的是哪一个券商的持仓。比如 有可能是 家人1-银河,家人2-国盛,这样的哈
下一篇:
【保姆教程】使用ptrade做一个持仓监控提醒软件 (二)
欢迎关注公众号:可转债量化分析 查看全部
因为有多个券商,比如银河,华宝,国金,国盛等。 而且也有家人的账户,可能一个银河就有5-6个账户。
所以如果持仓比较多的话,没有时间管得过来。 设置条件单比较繁琐,也不一定能管得过来。
要求:
把所有的持仓股Excel导出,输入的数据库(这里选择mysql),然后Ptrade读取了股票池,每隔3s扫描一次行情,如果遇到大涨或者大跌的个股,转债,ETF,就发送微信消息提醒(涨幅/跌幅大于7%)
这个是某个客户的简单需求。
后面就按照上面的需求做一个客户端,除了可以录入上述资料,还能提供web服务,输入,删除持仓股,做到实时更新。
最后提醒效果如下:
国金QMT的字样,用来区分我这个标的是哪一个券商的持仓。比如 有可能是 家人1-银河,家人2-国盛,这样的哈
下一篇:
【保姆教程】使用ptrade做一个持仓监控提醒软件 (二)
欢迎关注公众号:可转债量化分析
python量化分析教程 | 最近几年A股养老基金整体盈亏情况分析
股票 • 李魔佛 发表了文章 • 0 个评论 • 493 次浏览 • 2024-07-25 17:30
不仅是散户被深套,很多基金也都大幅亏损。甚至前阵子看到证券时报报道,养老目标基金都出现不是清盘的现象。
于是笔者好奇心驱使,想看看这些养老基金最近几年的盈利情况,会不会把长辈老人们的下半辈子养老金都亏空了。
作为一名授人以渔的公众号博主,不仅仅贴个收益率图出来这么简单的啦。如果只是想看数据,直接跳过前面的操作即可。
笔者手把手教大家做数据分析,学会后不仅仅只对养老基金这一类别的基金做分析,还可以对不同类型的基金做分析。
前提:电脑按照了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比买入主流宽基波动要小一些,但并非保本的理财工具,对于风险接受能力低的老一辈朋友,需要慎重考虑的。
原文数据可在公众号:
可转债量化分析
获取
查看全部
不仅是散户被深套,很多基金也都大幅亏损。甚至前阵子看到证券时报报道,养老目标基金都出现不是清盘的现象。
于是笔者好奇心驱使,想看看这些养老基金最近几年的盈利情况,会不会把长辈老人们的下半辈子养老金都亏空了。
作为一名授人以渔的公众号博主,不仅仅贴个收益率图出来这么简单的啦。如果只是想看数据,直接跳过前面的操作即可。
笔者手把手教大家做数据分析,学会后不仅仅只对养老基金这一类别的基金做分析,还可以对不同类型的基金做分析。
前提:电脑按照了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比买入主流宽基波动要小一些,但并非保本的理财工具,对于风险接受能力低的老一辈朋友,需要慎重考虑的。
原文数据可在公众号:
可转债量化分析
获取
优矿的回测引擎运行在python2.7,汗
李魔佛 发表了文章 • 0 个评论 • 399 次浏览 • 2024-07-22 11:59
回测引擎运行在 Python2.7 之上,请您使用 Python2.7 的写法进行策略编写。
居然回测引擎还在2.7,怪不得目前性能比较拉跨了呢。。。
不过话说,自从它的可转债数据收费之后,我就一直没有再使用优矿进行回测了。
查看全部
回测引擎运行在 Python2.7 之上,请您使用 Python2.7 的写法进行策略编写。
居然回测引擎还在2.7,怪不得目前性能比较拉跨了呢。。。
不过话说,自从它的可转债数据收费之后,我就一直没有再使用优矿进行回测了。
华宝证券 华宝期权宝 钱龙 客户端 无法下载的原因
股票 • 李魔佛 发表了文章 • 0 个评论 • 518 次浏览 • 2024-07-05 11:45
结果在华宝的官网 找到下载链接,但一直报错:
似乎其他软件也是报错。
500报错,应该是服务器的原因。
然后把链接复制下来:
https://download.cnhbstock.com/download/qlqqb/qlqqbpc/qqbfz.exe
把链接的https 改成 http,
浏览器会提示:
您的连接不是私密连接
攻击者可能会试图从 139.224.24.109 窃取您的信息(例如:密码、通讯内容或信用卡信息)。了解详情
NET::ERR_CERT_COMMON_NAME_INVALID
如果您想获得 Chrome 最高级别然后点击继续访问
结果就可以下载啦。
说实话,华宝这技术的确不咋地。
这个问题居然没有反馈,没有人去修复吗?
查看全部
结果在华宝的官网 找到下载链接,但一直报错:
似乎其他软件也是报错。
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 个评论 • 552 次浏览 • 2024-06-30 13:48
文档里面也有说明:
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的朋友,可以扫描关注关注号: 查看全部
文档里面也有说明:
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的朋友,可以扫描关注关注号:
QMT获取持仓信息报错:AttributeError: 'NoneType' object has no attribute 'request_id'
QMT • 李魔佛 发表了文章 • 0 个评论 • 529 次浏览 • 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 个评论 • 1000 次浏览 • 2024-05-29 12:02
成交了多少量,就融券多少量。达到指标即可停止。
代写量化程序,可以关注公众号,后台联系。 价格比QMT官网低的多了。实战性选手,选过N多QMT,ptrade实盘代码。
查看全部
Ptrade成交回调函数无法执行的原因? | ptrade bug
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 614 次浏览 • 2024-05-28 00:08
就是回调函数里面有一个字段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 是不会执行的!!!
天坑!
查看全部
就是回调函数里面有一个字段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 个评论 • 687 次浏览 • 2024-05-12 16:55
还有更多的缩进的问题。
pep8的规范早已经不用tab来做缩进,而是用4个空格。
之前的文章里面也提到了,可以在qmt的配置文件里面改的。不过在UI上是不提供修改的地方。
http://www.30daydo.com/article/44602
查看全部
以前喜欢用C替代ContextInfo,现在改过去了,又有部分改的不完整。
还有更多的缩进的问题。
pep8的规范早已经不用tab来做缩进,而是用4个空格。
之前的文章里面也提到了,可以在qmt的配置文件里面改的。不过在UI上是不提供修改的地方。
http://www.30daydo.com/article/44602
QMT里定时任务运行时间操作定时任务的间隔,会怎么样?
QMT • 李魔佛 发表了文章 • 0 个评论 • 695 次浏览 • 2024-05-06 10:32
当时任务运行时间超过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秒之后打印出来。
查看全部
当时任务运行时间超过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秒之后打印出来。
国盛证券的Ptrade数据无论是回测还是实盘很有问题,前复权不正确,数据断崖
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 835 次浏览 • 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,
在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的成分股与实时净值
QMT • 李魔佛 发表了文章 • 0 个评论 • 809 次浏览 • 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的朋友,可以扫码关注公众号开通: 查看全部
QMT回测会跳过当前的周六日和节假日吗
QMT • 李魔佛 发表了文章 • 0 个评论 • 725 次浏览 • 2024-04-09 13:13
比如回测日期选择 2024年3月28日到2024年4月2日。
其中3月30日和31日是周六日。
下面回测的数据是不执行这两天的数据。从3月30日 15:00的数据,下一个bar就是4月1日09:30了
需要低门槛开通量化QMT,Ptrade,可以扫码联系。
开通后可加入技术交流群。 查看全部
qmt下载完数据之后,记得重启一次qmt,不然get_market_data_ex依然还是获取不到数据的
QMT • 李魔佛 发表了文章 • 0 个评论 • 831 次浏览 • 2024-04-01 13:38
qmt下载完数据之后,get_market_data_ex依然还是获取不到数据。
其实主要数据没有刷新。
只需要你手动关闭QMT,再打开一次就好了。
反正呢,这些问题,QMT也不会告诉你,要靠自己摸索了。
欢迎收藏网站哦! 查看全部
QMT每次自动升级,都会把改过的配置文件给覆盖掉
QMT • 李魔佛 发表了文章 • 0 个评论 • 831 次浏览 • 2024-03-31 14:23
感觉设计模式有问题。
本来我配置了缩进用的4个空格,(这是pep8的标准好吧)
而qmt默认是用tab做缩进。
导致从vs code或者pycharm上的代码迁移迁移过来qmt的编辑器,你按tab键,是制表符,而不是4个空格。
运行或者回测就会报错。
每次升级都把我的配置给改了。
难道不覆盖config文件不行吗? 每次类似全量升级,一点点bug fix都在全量升级
查看全部
不同券商的数据质量简单对比:国金QMT vs 国信QMT(iquant)
QMT • 李魔佛 发表了文章 • 0 个评论 • 1516 次浏览 • 2024-03-31 11:57
点击打开大图
上面的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 !') 查看全部
点击打开大图
上面的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 !')
国金证券的融券数量多吗?什么是专项券源?
股票 • 李魔佛 发表了文章 • 0 个评论 • 833 次浏览 • 2024-03-30 17:13
那么融券呢?
今天特意问了下经理,他发了一个融券的表格给我。
目前国金里面一般开通了融资融券的投资者,可用的券源有290个左右,随借随还的。说实话,这个数量不算太多。
而且里面的个股,部分也只能融100股,几百股的。所以即使被你融到券,实际下来的绝对收益也不会太高。
不过它也有一个专项券源。
它有资金要求,前20个交易日日均资产不低于300万元,才能够申请。
发现里面的券,主要是深圳交易所的为主,占了90%以上。
而且专项券源里面的可融券数量也比普通券源的要多很多,几千股,上万股的。
公共券源 :
实时可借 ,随时可融券卖出, 随借随还,融券卖出开仓后最快下一交易日方可归还融券负债 信用账户融券费率 按使用天数计息,算头不算尾
操作步骤: 融券卖出(所有客户端)
专项券源:
实时可借 ,审批划拨成功后当日专项融券卖出, 固定期限(一般28天以内),不可提前归还 ;
专项融券头寸占用费率 : 按专项头寸合约期限计息,不论合约期限内客户是否使用券源,均需支付专项头寸合约占用利息,算头算尾
操作步骤:
第1步:专项融券头寸申请(佣金宝APP/国金太阳至强版)
第2步:专项融券卖出(佣金宝APP/国金太阳至强版)
查看全部
那么融券呢?
今天特意问了下经理,他发了一个融券的表格给我。
目前国金里面一般开通了融资融券的投资者,可用的券源有290个左右,随借随还的。说实话,这个数量不算太多。
而且里面的个股,部分也只能融100股,几百股的。所以即使被你融到券,实际下来的绝对收益也不会太高。
不过它也有一个专项券源。
它有资金要求,前20个交易日日均资产不低于300万元,才能够申请。
发现里面的券,主要是深圳交易所的为主,占了90%以上。
而且专项券源里面的可融券数量也比普通券源的要多很多,几千股,上万股的。
公共券源 :
实时可借 ,随时可融券卖出, 随借随还,融券卖出开仓后最快下一交易日方可归还融券负债 信用账户融券费率 按使用天数计息,算头不算尾
操作步骤: 融券卖出(所有客户端)
专项券源:
实时可借 ,审批划拨成功后当日专项融券卖出, 固定期限(一般28天以内),不可提前归还 ;
专项融券头寸占用费率 : 按专项头寸合约期限计息,不论合约期限内客户是否使用券源,均需支付专项头寸合约占用利息,算头算尾
操作步骤:
第1步:专项融券头寸申请(佣金宝APP/国金太阳至强版)
第2步:专项融券卖出(佣金宝APP/国金太阳至强版)
Ptrade|QMT|银行股息率轮动 实盘自动化交易
李魔佛 发表了文章 • 0 个评论 • 980 次浏览 • 2024-03-05 09:33
miniQMT安装包路径 | 下载地址
QMT • 李魔佛 发表了文章 • 0 个评论 • 1218 次浏览 • 2024-02-29 20:09
等待几分钟,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(低门槛,低费率)的朋友,
可以扫码联系:或者添加 技术公众号:
公众号:
查看全部
等待几分钟,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 个评论 • 1461 次浏览 • 2024-02-23 15:16
基本大家都用的银河证券或者华宝证券的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折。各个费率基本在同样档位里面是最低的了。
需要的朋友可以扫码联系开通: 查看全部
基本大家都用的银河证券或者华宝证券的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折。各个费率基本在同样档位里面是最低的了。
需要的朋友可以扫码联系开通: