QMT
QMT文件读写限制绕过
QMT • 李魔佛 发表了文章 • 0 个评论 • 133 次浏览 • 2026-10-20 19:33
而其QMT测试客户端在10月13日已经开始限制了。
简单测试了一下:
报错日子一看,FileIO已经没有权限写入。写入文件路径为 "D:\github\input.csv"
不过只要我把目录路径改成相对路径:"input.csv" , 数据是可以被写入且读取的。
这个路径是QMT安装目录下的子目录bin.x64,比如我的是: D:\tool\gjzq_qmt_simulation\bin.x64
这样就轻松绕过读写限制了。
其实上面的绝对路径的读取文件也是没有任何问题的,只是无法写入而已。
需要写入的话就使用相对路径。
网络的话,测试端使用requests请求一切正常,并没有限制。所以传递数据的时候使用API传给QMT访问是没有问题的。
QMT本地持久化
如果不想使用本地来存储,QMT系统提供了
save_py_key(key, value) 和 get_py_key(key)
两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。QMT系统提供了 save_py_key(key, value) 和 get_py_key(key) 两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。
函数说明:
save_py_key(key, value):保存数据
key :要保存的关键字, str 类型
value :要保存的值, str 类型
返回: errid (错误id,0表示成功), errmsg (错误信息,成功时为空字符串)
示例: errid, errmsg = save_py_key('关键字', '值')
get_py_key(key):读取数据
key :要读取的关键字, str 类型
返回: value (返回的值, str 类型), errid , errmsg
示例: value, errid, errmsg = get_py_key('关键字')
注意事项:
单字段长度限制为5000字符(英文1个字符,中文2个字符)。
该功能适用于在QMT系统对文件读写和网络连接进行限制后,替代本地文件存储中间变量的方案。
附测试使用代码:
# encoding:gbk
import json
def server_kv_store():
key = 'positions'
v = [{'symbol': '123456.SZ','base_pirce':100},{'symbol': '123457.SZ','base_pirce':200}]
kv = { key: json.dumps(v)}
# 保存键值对
print('保存数据',kv)
errid, errmsg = save_py_key(key, kv[key])
if errid != 0:
print("Failed to save key-value: ", errmsg)
return
print('保存成功,读取数据')
value, errid, errmsg = get_py_key(key)
if errid!=0:
print("Failed to get key-value: ", errmsg)
return
jvalue = json.loads(value)
print('读取数据', jvalue)
def init(ContextInfo):
# read_io()
# network_io()
server_kv_store()
def handlebar(ContextInfo):
pass
在测试客户端上测试通过。
value的参数类型是str,所以dict,list这些类型需要json.dump序列化一下,不然会报错。
不同券商遇到的问题不同,到时QMT实盘客户端也可能有不同的限制,可评论留言。
关注公众号: 查看全部
而其QMT测试客户端在10月13日已经开始限制了。
简单测试了一下:
报错日子一看,FileIO已经没有权限写入。写入文件路径为 "D:\github\input.csv"
不过只要我把目录路径改成相对路径:"input.csv" , 数据是可以被写入且读取的。
这个路径是QMT安装目录下的子目录bin.x64,比如我的是: D:\tool\gjzq_qmt_simulation\bin.x64
这样就轻松绕过读写限制了。
其实上面的绝对路径的读取文件也是没有任何问题的,只是无法写入而已。
需要写入的话就使用相对路径。
网络的话,测试端使用requests请求一切正常,并没有限制。所以传递数据的时候使用API传给QMT访问是没有问题的。
QMT本地持久化
如果不想使用本地来存储,QMT系统提供了
save_py_key(key, value) 和 get_py_key(key)
两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。
QMT系统提供了 save_py_key(key, value) 和 get_py_key(key) 两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。
函数说明:
save_py_key(key, value):保存数据
key :要保存的关键字, str 类型
value :要保存的值, str 类型
返回: errid (错误id,0表示成功), errmsg (错误信息,成功时为空字符串)
示例: errid, errmsg = save_py_key('关键字', '值')
get_py_key(key):读取数据
key :要读取的关键字, str 类型
返回: value (返回的值, str 类型), errid , errmsg
示例: value, errid, errmsg = get_py_key('关键字')
注意事项:
单字段长度限制为5000字符(英文1个字符,中文2个字符)。
该功能适用于在QMT系统对文件读写和网络连接进行限制后,替代本地文件存储中间变量的方案。
附测试使用代码:
# encoding:gbk
import json
def server_kv_store():
key = 'positions'
v = [{'symbol': '123456.SZ','base_pirce':100},{'symbol': '123457.SZ','base_pirce':200}]
kv = { key: json.dumps(v)}
# 保存键值对
print('保存数据',kv)
errid, errmsg = save_py_key(key, kv[key])
if errid != 0:
print("Failed to save key-value: ", errmsg)
return
print('保存成功,读取数据')
value, errid, errmsg = get_py_key(key)
if errid!=0:
print("Failed to get key-value: ", errmsg)
return
jvalue = json.loads(value)
print('读取数据', jvalue)
def init(ContextInfo):
# read_io()
# network_io()
server_kv_store()
def handlebar(ContextInfo):
pass
在测试客户端上测试通过。
value的参数类型是str,所以dict,list这些类型需要json.dump序列化一下,不然会报错。
不同券商遇到的问题不同,到时QMT实盘客户端也可能有不同的限制,可评论留言。
关注公众号:
国金证券, 国投证券 QMT 的IO文件功能被禁止
QMT • 李魔佛 发表了文章 • 0 个评论 • 886 次浏览 • 2026-10-12 09:14
下面是券商的公告:
系统预留信息
【重要】内置Python策略功能调整
2026-10-08 00:00:00
[重要]尊敬的投资者:
为进一步规范迅投QMT系统功能,我部近期将对有关功能模块进行调整,具体如下:
一、关闭内置Python策略文件读写功能
涉及本地文件读写的功能(包括但不限于open()、read()、write()及相关第三方库)均无法使用。
二、关闭内置Python策略外部网络连接功能
涉及策略发起的网络连接(包括但不限于HTTP、TCP、UDP等)、局域网或本机数据库连接(包括但不限于MYSQL、Redis、SQLite等)以及与局域网内其他设备进行网络通信、网络IP地址与网络端口的连接及涉及上述的相关三方库均会被禁止。
三、取消登录页的独立交易选项
本次功能升级,将会一并取消登录页的独立交易选项,如您的系统界面仍有此按钮,请尽快在本次升级完成后登录我司官网下载最新客户端。
本次升级将于10月23日完成,使用内置python,且不与外部进行任何交互的策略不受上述调整影响。
这次整治, 是因为有些人利用QMT,miniQMT 售卖策略. 但他们不是给你源码, 因为源码卖出是一次性的. 他们为了更长远的割韭菜, 它们提供的参数配置, 需要你去开户, 然后使用QMT账号, 连接他们的系统, 你只能修改一些策略参数, 定制化程度比较低, 策略同质化比较严重, 如果资金量大的人, 还很容易被他们内部收割. 比如你设置的参数止盈是涨幅5%, 他们内部可以设置另一个策略, 止盈为4.5% , 就可以在你之前出货.
目前已知的黑平台有云飞量化, 禄得lude.cc 这些, 这次也是因为它们导致miniQMT被查封的. 查看全部
下面是券商的公告:
系统预留信息
【重要】内置Python策略功能调整
2026-10-08 00:00:00
[重要]尊敬的投资者:
为进一步规范迅投QMT系统功能,我部近期将对有关功能模块进行调整,具体如下:
一、关闭内置Python策略文件读写功能
涉及本地文件读写的功能(包括但不限于open()、read()、write()及相关第三方库)均无法使用。
二、关闭内置Python策略外部网络连接功能
涉及策略发起的网络连接(包括但不限于HTTP、TCP、UDP等)、局域网或本机数据库连接(包括但不限于MYSQL、Redis、SQLite等)以及与局域网内其他设备进行网络通信、网络IP地址与网络端口的连接及涉及上述的相关三方库均会被禁止。
三、取消登录页的独立交易选项
本次功能升级,将会一并取消登录页的独立交易选项,如您的系统界面仍有此按钮,请尽快在本次升级完成后登录我司官网下载最新客户端。
本次升级将于10月23日完成,使用内置python,且不与外部进行任何交互的策略不受上述调整影响。
这次整治, 是因为有些人利用QMT,miniQMT 售卖策略. 但他们不是给你源码, 因为源码卖出是一次性的. 他们为了更长远的割韭菜, 它们提供的参数配置, 需要你去开户, 然后使用QMT账号, 连接他们的系统, 你只能修改一些策略参数, 定制化程度比较低, 策略同质化比较严重, 如果资金量大的人, 还很容易被他们内部收割. 比如你设置的参数止盈是涨幅5%, 他们内部可以设置另一个策略, 止盈为4.5% , 就可以在你之前出货.
目前已知的黑平台有云飞量化, 禄得lude.cc 这些, 这次也是因为它们导致miniQMT被查封的.
国信证券iquant(QMT) 相比其他券商 有什么优势?
QMT • 李魔佛 发表了文章 • 0 个评论 • 583 次浏览 • 2026-09-05 16:17
国信QMT(相对于其他券商的QMT软件的优势),PS: 国信的QMT叫iquant,界面加了一些功能。
一、国信QMT历史数据更丰富,下载不受限制,从股票上市就有,其他券商只有最近三年的历史数据。
二、国信QMT的L1(tick)行情数据免费使用,支持盘口五档以及分笔数据,其他券商只有三档。
三、国信QMT支持算法交易以及云服务器运行,其他券商不支持。
五、国信QMT支持多点登录,也就是多个电脑同事登录一个账号,其他券商不支持。
六、国信QMT申请实盘简单,开户后T+1申请实盘,不用邮寄资料,其他券商需要客户邮寄资料。
七、国信是头部券商,全国各地都有营业部,客户办理高端业务,临柜方便,国信证券提供量化技术支持服务。
国信有miniQMT,可以拿去获取数据,回测,但是不能去下单。
查看全部
国信QMT(相对于其他券商的QMT软件的优势),PS: 国信的QMT叫iquant,界面加了一些功能。
一、国信QMT历史数据更丰富,下载不受限制,从股票上市就有,其他券商只有最近三年的历史数据。
二、国信QMT的L1(tick)行情数据免费使用,支持盘口五档以及分笔数据,其他券商只有三档。
三、国信QMT支持算法交易以及云服务器运行,其他券商不支持。
五、国信QMT支持多点登录,也就是多个电脑同事登录一个账号,其他券商不支持。
六、国信QMT申请实盘简单,开户后T+1申请实盘,不用邮寄资料,其他券商需要客户邮寄资料。
七、国信是头部券商,全国各地都有营业部,客户办理高端业务,临柜方便,国信证券提供量化技术支持服务。
国信有miniQMT,可以拿去获取数据,回测,但是不能去下单。
ptrade运行的策略全部不见了 | 国金证券
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 536 次浏览 • 2026-08-14 12:06
正常运行和已停止的都不见了。
在回测页面里面能看到之前的写的策略。
客服回应说 服务器内存不足造成,重启环境之后,上报给他们可以找回。
不过问题是策略已经停止了,找回正常运行的策略也是要自己启动,还不如我自己重新新建策略,重新启动得了。
所以使用ptrade,最后把平时的输出日志保存为文件,自动存储到研究的jupyter notebook下面。
这样就能够在策略重启,无故消失的情况下,找回丢失的日志。
查看全部
正常运行和已停止的都不见了。
在回测页面里面能看到之前的写的策略。
客服回应说 服务器内存不足造成,重启环境之后,上报给他们可以找回。
不过问题是策略已经停止了,找回正常运行的策略也是要自己启动,还不如我自己重新新建策略,重新启动得了。
所以使用ptrade,最后把平时的输出日志保存为文件,自动存储到研究的jupyter notebook下面。
这样就能够在策略重启,无故消失的情况下,找回丢失的日志。
华泰QMT下载 | 华泰支持迅投QMT了
QMT • 李魔佛 发表了文章 • 0 个评论 • 636 次浏览 • 2026-08-03 10:41
华泰迅投QMT系统是专门为专业交易客户打造的集合策略投研、交易执行、行情展示、风控管理为一体的综合投研交易终端。策略研究包括数据管理、策略研究、策略风控等功能;支持组合交易、算法交易、对冲交易、机构风格下单等高效的交易功能,满足不同投资者的多样化交易需求。
QMT下载地址:
https://inst.htsc.com/helpOnline?productId=60&moduleCode=1
它支持自定义编程模块,可以自己编程下单。
接口文档:https://qmt.ptradeapi.com
查看全部
华泰迅投QMT系统是专门为专业交易客户打造的集合策略投研、交易执行、行情展示、风控管理为一体的综合投研交易终端。策略研究包括数据管理、策略研究、策略风控等功能;支持组合交易、算法交易、对冲交易、机构风格下单等高效的交易功能,满足不同投资者的多样化交易需求。
QMT下载地址:
https://inst.htsc.com/helpOnline?productId=60&moduleCode=1
它支持自定义编程模块,可以自己编程下单。
接口文档:https://qmt.ptradeapi.com
miniQMT停用后,外部调用QMT内部函数的路子
QMT • 李魔佛 发表了文章 • 0 个评论 • 1326 次浏览 • 2026-07-02 08:56
但办法总比困难多,其中一个方法是在QMT里开一个HTTP的REST API服务,外部可以调用这个HTTP API,达到下单,撤单,查询持仓,获取行情等所有在QMT下所需要的功能。
目前QMT内置的python版本为3.6.8,你可以在里面安装各种第三方web框架,fastapi,django,flask等。而QMT原来内置了tornado,就不需要额外安装其他第三方库了。文末提供完整源码地址。
导入所需要的库
from tornado.web import Application, RequestHandler, HTTPError
from tornado.ioloop import IOLoop
程序核心就是在QMT的init函数里面就启动我们的HTTP服务,端口PORT随意。
PORT = 10086
ACCOUNT_ID = '你的QMT账号'
def init(ContextInfo):
try:
ContextInfo.accountID = ACCOUNT_ID
app = make_app()
app.ContextInfo = ContextInfo
app.accountID = ContextInfo.accountID
app.listen(PORT, address='0.0.0.0') # 如果只在本地网络,可以设置为127.0.0.1
logger.info(f"QMT HTTP Server 启动于 http://0.0.0.0:{PORT} (全部API已加载)")
IOLoop.current().start()
except Exception as e:
logger.exception(f"server start failed: {e}")
make_app里提供的注册路由。
============= 路由注册 =============
def make_app():
return Application([
# 原有兼容路由
(r"/api/holding", HoldingHandler),
(r"/api/money/total", TotalMoneyHandler),
(r"/api/money/available", AvailableMoneyHandler),
(r"/api/order/buy", BuyHandler),
(r"/api/order/sell", SellHandler),
(r"/api/order/deal", DealHandler),
..... 省略若干
# 数据查询
(r"/api/data/stock_name", StockNameHandler),
(r"/api/data/open_date", OpenDateHandler),
(r"/api/data/last_volume", LastVolumeHandler),
(r"/api/data/bar_timetag", BarTimetagHandler),
(r"/api/data/tick_timetag", TickTimetagHandler),
(r"/api/data/sector", SectorHandler),
(r"/api/data/industry", IndustryHandler),
(r"/api/data/stock_list_in_sector", StockListInSectorHandler),
(r"/api/data/history_data", HistoryDataHandler),
(r"/api/data/market_data", MarketDataHandler),
(r"/api/data/market_data_ex", MarketDataExHandler),
(r"/api/data/full_tick", FullTickHandler),
每个API实现一个原QMT的函数,所以有非常多的API端点。
当然这些函数我都让AI帮我对着QMT的文档实现的。
接口文档:https://qmt.ptradeapi.com/QMT_Python_API_Doc.html
然后FullTickHandler的实现如下:
# ContextInfo.get_full_tick() - 获取分笔数据
class FullTickHandler(BaseHandler):
def post(self):
data = json.loads(self.request.body)
stocks = data.get('stocks', '')
if not stocks:
raise HTTPError(400, "need args stocks")
code_list = [s.strip() for s in stocks.split(',')]
ret = safe_call(self.ctx().get_full_tick, code_list)
if not ret:
raise HTTPError(500, "获取分笔行情失败")
self.write(json.dumps(ret, ensure_ascii=False, default=str))
这里核心就是执行QMT的get_full_tick,把数据作为response返回。请求使用POST,传入股票代码,返回股票tick数据。
在QMT里启动后,等待外部程序调用。
上面是把完整代码复制到QMT里,然后在实盘里面启动。
然后在你外部的程序里面写个简单的HTTP请求,就能调用QMT里面的API了。
如果你的电脑有公网IP,还可以不同电脑去远程调用QMT里面的函数,
这里加入一个任意TOKEN,和QMT里面一致就行,这样请求的header带上,避免其他人调用你的API操作你账号。如果只在本地运行,可以把最开始的监听地址0.0.0.0改为127.0.0.1
TOKEN = "123456789"
class QMTClient:
def __init__(self, base_url="http://127.0.0.1:10086"):
self.base = base_url
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json; charset=utf-8"})
self.session.headers.update({"X-Token": TOKEN})
def _req(self, method, path, **kwargs):
url = f"{self.base}{path}"
try:
resp = self.session.request(method, url, timeout=10, **kwargs)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
return {"error": str(e), "status_code": getattr(e.response, 'status_code', 500)}
def get_full_tick(self, stocks):
return self._req('POST', f'/api/data/full_tick', json={
"stocks": stocks})
client = QMTClient()
print(client.get_full_tick('600000.SH'))
client = QMTClient()
print(client.get_full_tick('600000.SH'))
QMT里可以看到对应的调用记录
外部程序的返回的结果:
然后按葫芦画瓢,让AI对着文档把剩余的函数都实现了即可。
比如要下单功能,就实现
# passorder(23) - 买入下单(封装passorder)
class BuyHandler(BaseHandler):
def post(self):
try:
data = json.loads(self.request.body)
stock = data['stock']
price = float(data['price'])
volume = int(data['volume'])
pr_type = data.get('prType', 11)
order_ref = passorder(23, 1101, self.acc(), stock, pr_type, price, volume, 'qmt', 2, self.ctx())
self.write(json.dumps({
"status": "success", "action": "buy", "stock": stock,
"order_ref": str(order_ref) if order_ref else"unknown"
}, ensure_ascii=False))
except Exception as e:
logger.exception("买入下单异常")
raise HTTPError(400, f"下单失败: {str(e)}")
然后在外部你的策略代码里面加入:
client = QMTClient()
client.buy_stock("600000.SZ", 6.80, 100)
即可完成下单,然后可以通过API查询持仓,获取最新状态。这样就不用把你策略嵌入到QMT里。
完整源码在github: https://github.com/Rockyzsu/QMT,(不确定是否AI封装的函数全部正确,会偶尔更新一下)
或者关注公众号"可转债量化分析",后台回复关键字:QMT封装
查看全部
但办法总比困难多,其中一个方法是在QMT里开一个HTTP的REST API服务,外部可以调用这个HTTP API,达到下单,撤单,查询持仓,获取行情等所有在QMT下所需要的功能。
目前QMT内置的python版本为3.6.8,你可以在里面安装各种第三方web框架,fastapi,django,flask等。而QMT原来内置了tornado,就不需要额外安装其他第三方库了。文末提供完整源码地址。
导入所需要的库
from tornado.web import Application, RequestHandler, HTTPError
from tornado.ioloop import IOLoop
程序核心就是在QMT的init函数里面就启动我们的HTTP服务,端口PORT随意。
PORT = 10086
ACCOUNT_ID = '你的QMT账号'
def init(ContextInfo):
try:
ContextInfo.accountID = ACCOUNT_ID
app = make_app()
app.ContextInfo = ContextInfo
app.accountID = ContextInfo.accountID
app.listen(PORT, address='0.0.0.0') # 如果只在本地网络,可以设置为127.0.0.1
logger.info(f"QMT HTTP Server 启动于 http://0.0.0.0:{PORT} (全部API已加载)")
IOLoop.current().start()
except Exception as e:
logger.exception(f"server start failed: {e}")
make_app里提供的注册路由。
============= 路由注册 =============
def make_app():
return Application([
# 原有兼容路由
(r"/api/holding", HoldingHandler),
(r"/api/money/total", TotalMoneyHandler),
(r"/api/money/available", AvailableMoneyHandler),
(r"/api/order/buy", BuyHandler),
(r"/api/order/sell", SellHandler),
(r"/api/order/deal", DealHandler),
..... 省略若干
# 数据查询
(r"/api/data/stock_name", StockNameHandler),
(r"/api/data/open_date", OpenDateHandler),
(r"/api/data/last_volume", LastVolumeHandler),
(r"/api/data/bar_timetag", BarTimetagHandler),
(r"/api/data/tick_timetag", TickTimetagHandler),
(r"/api/data/sector", SectorHandler),
(r"/api/data/industry", IndustryHandler),
(r"/api/data/stock_list_in_sector", StockListInSectorHandler),
(r"/api/data/history_data", HistoryDataHandler),
(r"/api/data/market_data", MarketDataHandler),
(r"/api/data/market_data_ex", MarketDataExHandler),
(r"/api/data/full_tick", FullTickHandler),
每个API实现一个原QMT的函数,所以有非常多的API端点。
当然这些函数我都让AI帮我对着QMT的文档实现的。
接口文档:https://qmt.ptradeapi.com/QMT_Python_API_Doc.html
然后FullTickHandler的实现如下:
# ContextInfo.get_full_tick() - 获取分笔数据
class FullTickHandler(BaseHandler):
def post(self):
data = json.loads(self.request.body)
stocks = data.get('stocks', '')
if not stocks:
raise HTTPError(400, "need args stocks")
code_list = [s.strip() for s in stocks.split(',')]
ret = safe_call(self.ctx().get_full_tick, code_list)
if not ret:
raise HTTPError(500, "获取分笔行情失败")
self.write(json.dumps(ret, ensure_ascii=False, default=str))
这里核心就是执行QMT的get_full_tick,把数据作为response返回。请求使用POST,传入股票代码,返回股票tick数据。
在QMT里启动后,等待外部程序调用。
上面是把完整代码复制到QMT里,然后在实盘里面启动。
然后在你外部的程序里面写个简单的HTTP请求,就能调用QMT里面的API了。
如果你的电脑有公网IP,还可以不同电脑去远程调用QMT里面的函数,
这里加入一个任意TOKEN,和QMT里面一致就行,这样请求的header带上,避免其他人调用你的API操作你账号。如果只在本地运行,可以把最开始的监听地址0.0.0.0改为127.0.0.1
TOKEN = "123456789"
class QMTClient:
def __init__(self, base_url="http://127.0.0.1:10086"):
self.base = base_url
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json; charset=utf-8"})
self.session.headers.update({"X-Token": TOKEN})
def _req(self, method, path, **kwargs):
url = f"{self.base}{path}"
try:
resp = self.session.request(method, url, timeout=10, **kwargs)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
return {"error": str(e), "status_code": getattr(e.response, 'status_code', 500)}
def get_full_tick(self, stocks):
return self._req('POST', f'/api/data/full_tick', json={
"stocks": stocks})
client = QMTClient()
print(client.get_full_tick('600000.SH'))
client = QMTClient()
print(client.get_full_tick('600000.SH'))
QMT里可以看到对应的调用记录
外部程序的返回的结果:
然后按葫芦画瓢,让AI对着文档把剩余的函数都实现了即可。
比如要下单功能,就实现
# passorder(23) - 买入下单(封装passorder)
class BuyHandler(BaseHandler):
def post(self):
try:
data = json.loads(self.request.body)
stock = data['stock']
price = float(data['price'])
volume = int(data['volume'])
pr_type = data.get('prType', 11)
order_ref = passorder(23, 1101, self.acc(), stock, pr_type, price, volume, 'qmt', 2, self.ctx())
self.write(json.dumps({
"status": "success", "action": "buy", "stock": stock,
"order_ref": str(order_ref) if order_ref else"unknown"
}, ensure_ascii=False))
except Exception as e:
logger.exception("买入下单异常")
raise HTTPError(400, f"下单失败: {str(e)}")
然后在外部你的策略代码里面加入:
client = QMTClient()
client.buy_stock("600000.SZ", 6.80, 100)
即可完成下单,然后可以通过API查询持仓,获取最新状态。这样就不用把你策略嵌入到QMT里。
完整源码在github: https://github.com/Rockyzsu/QMT,(不确定是否AI封装的函数全部正确,会偶尔更新一下)
或者关注公众号"可转债量化分析",后台回复关键字:QMT封装
miniQMT要被暂停使用了吗
QMT • 李魔佛 发表了文章 • 0 个评论 • 990 次浏览 • 2026-07-01 18:26
国X证券的通知:
但其他券商没有收到这个消息,所以其他券商依然能够正常使用。
从反馈的情况来看,是国X证券大面积推广这个miniQMT,导致同行反馈,被举报导致的。
其他规模不大的券商目前来看依然是安全的。
查看全部
ptrade支持redis吗
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 624 次浏览 • 2026-06-25 13:49
在ptrade的研究页面里面,输入:
import redis就是直接报错:
/usr/local/python3.5/lib/python3.5/site-packages/fly/data/quotation.py:133: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-92da440a6abd> in <module>()
3 except Exception as e:
4 from fly.data.quotation import *
----> 5 import redis
ImportError: No module named 'redis'
查看全部
在ptrade的研究页面里面,输入:
import redis就是直接报错:
/usr/local/python3.5/lib/python3.5/site-packages/fly/data/quotation.py:133: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-92da440a6abd> in <module>()
3 except Exception as e:
4 from fly.data.quotation import *
----> 5 import redis
ImportError: No module named 'redis'
国盛ptrade的版本升级到3.11,但无法连接外部网络了 | 最新更新:可以申请访问
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 782 次浏览 • 2026-06-24 20:52
最新更新,现在又能够申请访问了,
不少人说国盛的ptrade内置python版本低,是3.5的。
现在迎来了大版本升级,新开户的用户会升级到内置python3.11,运行效率会有相应的提高。
但坏消息是,原本支持的访问外网的功能会被移除。也就是新用户只能使用内置的ptrade数据。没法访问自己的数据库,也没法爬虫,没法接收自己的信号。
requests请求qq.com 超时:
后续更新:
可以申购额外的访问权限,只需要提供下你要访问的域名地址或者IP端口。比如你的mysql服务器ip,既可以让ptrade访问你的服务器。从而获取数据。
需要开通国盛ptrade的,可以扫码联系:
查看全部
最新更新,现在又能够申请访问了,
不少人说国盛的ptrade内置python版本低,是3.5的。
现在迎来了大版本升级,新开户的用户会升级到内置python3.11,运行效率会有相应的提高。
但坏消息是,原本支持的访问外网的功能会被移除。也就是新用户只能使用内置的ptrade数据。没法访问自己的数据库,也没法爬虫,没法接收自己的信号。
requests请求qq.com 超时:
后续更新:
可以申购额外的访问权限,只需要提供下你要访问的域名地址或者IP端口。比如你的mysql服务器ip,既可以让ptrade访问你的服务器。从而获取数据。
需要开通国盛ptrade的,可以扫码联系:

华泰证券支持QMT和Ptrade吗?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 1248 次浏览 • 2026-04-28 17:21
已更新。
目前华泰新增支持QMT。门槛入金50w。
### 2026-05 发布的 ####不支持。
目前为止,华泰没有Ptrade和QMT,华泰的量化平台用的是Matic。
好多AI读取的垃圾语料, 污染了返回结果.
里面有个模块MQuant。用于编写量化程序,支持python和C++
matic文档:
https://github.com/Rockyzsu/matic.git
需要开通的朋友可以扫码关注公众号,获取开通联系方式:
查看全部
已更新。
目前华泰新增支持QMT。门槛入金50w。
### 2026-05 发布的 ####不支持。
目前为止,华泰没有Ptrade和QMT,华泰的量化平台用的是Matic。
好多AI读取的垃圾语料, 污染了返回结果.
里面有个模块MQuant。用于编写量化程序,支持python和C++
matic文档:
https://github.com/Rockyzsu/matic.git
需要开通的朋友可以扫码关注公众号,获取开通联系方式:

湘财证券开通ptrade门槛
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1813 次浏览 • 2026-03-04 16:56
其文档地址: http://tushare.xcsc.com:7173/document/2
所以湘财证券也有内置的免费的tushare,
import xcsc_tushare as ts 它不限制积分,还可以免费一直使用。
xcsc tushare的数据相比官网的tushare会少一些数据。比如爬虫部分的数据。
目前湘财的费率是
股票 万0.854
ETF/LOF 万0.5
可转债 万1开通ptrade的门槛是入金1w,足够低。
目前湘财证券的ptrade是基于python3.11的最新版本。
需要的朋友可以咨询公众号: 查看全部
其文档地址: http://tushare.xcsc.com:7173/document/2
所以湘财证券也有内置的免费的tushare,
import xcsc_tushare as ts它不限制积分,还可以免费一直使用。
xcsc tushare的数据相比官网的tushare会少一些数据。比如爬虫部分的数据。
目前湘财的费率是
股票 万0.854开通ptrade的门槛是入金1w,足够低。
ETF/LOF 万0.5
可转债 万1
目前湘财证券的ptrade是基于python3.11的最新版本。
需要的朋友可以咨询公众号:
ptrade上 2个策略A和B同时运行,A策略成交时触发的回调事件会被B策略捕获吗?
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1322 次浏览 • 2026-02-12 01:10
那么如果A策略有股票成交,那么会触发A策略里面的成交回调函数on_trade_response,但B策略里面的on_trade_response 不会捕获这个成交所触发的成交回调。
更新关于ptrade的解答,可以关注:
https://ptradeapi.com/hub/data/qa_data.html
可以关注公众号或者星球。 查看全部
那么如果A策略有股票成交,那么会触发A策略里面的成交回调函数on_trade_response,但B策略里面的on_trade_response 不会捕获这个成交所触发的成交回调。
更新关于ptrade的解答,可以关注:
https://ptradeapi.com/hub/data/qa_data.html
可以关注公众号或者星球。
山西证券开通ptrade门槛 万0.854免5 | 山西证券ptrade下载地址
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2029 次浏览 • 2025-12-27 19:00
主要python3.11移除了pandas里的panel格式。导致之前ptrade获取到的3维数据不再兼容当前的最新版本。
山西证券ptrade下载地址:
山西证券ptrade实盘下载链接
山西证券ptrade仿真模拟下载链接
其实,个人感觉,现在的ptrade更加好用,不用再考虑不同的数据输入,来判读不同的返回结果。
get_history 函数,无论什么情况,都是返回dataframe格式。字段也是完全统一了
使用 sub_df = df[df['code']=code]
就能获取不同的输入格式。
换以前,如果传入的是一个字段 get_history(fields='close') 和get_history(fields=['low','close'])
返回的格式还得区分处理。
现在统一了,更加好用了。
目前山西证券ptrade开通门槛很低,入金5w就可以开通,而且费率是免5,万0.854免5,0.1起步,目前这么多券商里面是属于最低的了。
需要的朋友可以联系微信公众号开通:
查看全部
主要python3.11移除了pandas里的panel格式。导致之前ptrade获取到的3维数据不再兼容当前的最新版本。
山西证券ptrade下载地址:
山西证券ptrade实盘下载链接
山西证券ptrade仿真模拟下载链接
其实,个人感觉,现在的ptrade更加好用,不用再考虑不同的数据输入,来判读不同的返回结果。
get_history 函数,无论什么情况,都是返回dataframe格式。字段也是完全统一了
使用 sub_df = df[df['code']=code]
就能获取不同的输入格式。
换以前,如果传入的是一个字段 get_history(fields='close') 和get_history(fields=['low','close'])
返回的格式还得区分处理。
现在统一了,更加好用了。
目前山西证券ptrade开通门槛很低,入金5w就可以开通,而且费率是免5,万0.854免5,0.1起步,目前这么多券商里面是属于最低的了。
需要的朋友可以联系微信公众号开通:

东莞证券ptrade的编程功能模块被移除了
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1875 次浏览 • 2025-11-23 13:17
本来门槛不太高,作为备用也是不错的.
也不知道上面领导怎么想的. 把编程模块移走了.
目前就剩ptrade上内置的一些基础功能
无法通过python编程实现自己的自定义策略.
有点可惜.
查看全部
ptrade不支持reits,连持仓已有的也读取不出来
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1575 次浏览 • 2025-11-18 12:45
然后调用get_positions获取持仓,居然为空。
开始以为我程序代码后缀有问题,百思不得其解,反复检查之后,突然想起目前的ptrade不支持reits品种。
但没想到居然这个持仓代码都读取不到。。。
查看全部
然后调用get_positions获取持仓,居然为空。
开始以为我程序代码后缀有问题,百思不得其解,反复检查之后,突然想起目前的ptrade不支持reits品种。
但没想到居然这个持仓代码都读取不到。。。
指数回来了,收益没回来!十年前 4000 点买入,多少股票至今没回本?
股票 • 李魔佛 发表了文章 • 0 个评论 • 1958 次浏览 • 2025-10-29 08:58
可惜只持续了40分钟,收盘时跌回到3988点。
不过本轮并不是全面的牛市,没在暴涨板块的股民自嘲:
8000点的农行,6000点的科技,4000点的红利,剩下的全是2000点的难兄难弟。
十年光阴荏苒,上证指数上一次收盘价超过 4000 点是在 2015 年 7 月 24 日,当日收于 4070.91 点。
指数重回4000点,而又有多少股票的股价能够重回十年前4000点的时候股价呢?或者说还有多少股票依然还在以前4000点的时候的股价还低呢?
问了一下豆包,deepseek这个问题,结果说找不到现成的数据,无法分析。
迅速在ptrade上写个代码查询一下。
2015 年 7 月 24 日 市场有有沪深股票2783只,而当时的2783只股票今天依然在市场交易的有2567只。大约有216只股票退市(少数是合并、收购,大部分原因是退市)。
也就是十年前扔飞镖随便买一只股票,会有7.7%的概率买到退市股,并且是那种目前彻底退出的沪深板块,流入到退市板块。
下面列出期间的退市股(含收购合并),数据较多,对细节不感兴趣的可直接滚动到最后。
依然在交易的排除掉7只停牌的股票,有2559只存续交易的股票。
跌幅榜的排名。
不少跌幅达到80%-90%,不少是当时的牛股,全通交易,怡亚通,ST易购(苏宁易购),康美药业,万达电影等等。
跌幅为0的排到1662名了。数据太长,贴不下了。
也就是上证指数回到上一次的4000点,有1661只个股依然没有回到当时的股价,占比达到了64.9%。(注意,上面的股价是前复权的价格,是已经包含了分红的全收益价格。)
看完这个数据整个人都不太好受了,股民的十年青春在股海沉浮,最终超过一半的个股还没有回到牛市的起点。 查看全部
可惜只持续了40分钟,收盘时跌回到3988点。
不过本轮并不是全面的牛市,没在暴涨板块的股民自嘲:
8000点的农行,6000点的科技,4000点的红利,剩下的全是2000点的难兄难弟。
十年光阴荏苒,上证指数上一次收盘价超过 4000 点是在 2015 年 7 月 24 日,当日收于 4070.91 点。
指数重回4000点,而又有多少股票的股价能够重回十年前4000点的时候股价呢?或者说还有多少股票依然还在以前4000点的时候的股价还低呢?
问了一下豆包,deepseek这个问题,结果说找不到现成的数据,无法分析。
迅速在ptrade上写个代码查询一下。
2015 年 7 月 24 日 市场有有沪深股票2783只,而当时的2783只股票今天依然在市场交易的有2567只。大约有216只股票退市(少数是合并、收购,大部分原因是退市)。
也就是十年前扔飞镖随便买一只股票,会有7.7%的概率买到退市股,并且是那种目前彻底退出的沪深板块,流入到退市板块。
下面列出期间的退市股(含收购合并),数据较多,对细节不感兴趣的可直接滚动到最后。
依然在交易的排除掉7只停牌的股票,有2559只存续交易的股票。
跌幅榜的排名。
不少跌幅达到80%-90%,不少是当时的牛股,全通交易,怡亚通,ST易购(苏宁易购),康美药业,万达电影等等。
跌幅为0的排到1662名了。数据太长,贴不下了。
也就是上证指数回到上一次的4000点,有1661只个股依然没有回到当时的股价,占比达到了64.9%。(注意,上面的股价是前复权的价格,是已经包含了分红的全收益价格。)
看完这个数据整个人都不太好受了,股民的十年青春在股海沉浮,最终超过一半的个股还没有回到牛市的起点。
东北证券QMT miniQMT (NET专业版)万0.854免5
QMT • 李魔佛 发表了文章 • 0 个评论 • 4861 次浏览 • 2025-10-16 23:05
东北证券的qmt名称叫NET专业版。
东北证券的QMT支持python和vba 两种语言。
开通后可加入量化技术群。
扫码联系开通。 查看全部
ptrade支持北交所股票量化交易吗?
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2118 次浏览 • 2025-10-09 11:36
文档里面搜不到内容,股票后缀使用 北交所代码+ SS后缀,或者 .BJ 后缀,获取不到任何的数据。
ptrade api 文档:
https://ptradeapi.com
查看全部
文档里面搜不到内容,股票后缀使用 北交所代码+ SS后缀,或者 .BJ 后缀,获取不到任何的数据。
ptrade api 文档:
https://ptradeapi.com
山西证券Ptrade 万一免五开户
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2400 次浏览 • 2025-09-26 01:44
本身山西证券的ptrade开通门槛不高, 入金5万就能开通ptrade,永久使用,不收费.
不过默认费率比较高, 也不免5.
不过入金5w后,是可以调到万一免5的.
因为高顿教育的量化课程使用的是山西证券作为 实例,所以也有不少的群众基础.
需要的可以扫码关注开通.
查看全部
Ptrade ETF轮动,收益率秒杀白云飞
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2321 次浏览 • 2025-09-11 20:07
如果抛去924行情,和今年的创业板+科创板,CPO,芯片,那么它的收益率是负的。漫长的3年回撤期,除非是闲钱很久不用的钱,否则谁也无法忍受这么长的回撤。
而ETF日,周净增轮动+动量+板块温度计+评分因子,可以做到超高的收益率。
使用ptrade进行回测。
使用ptrade进行实盘。
TBC
查看全部
ptrade计算EMA指标,对比同花顺
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2617 次浏览 • 2025-09-01 23:04
初始值计算:
标准 EMA:以周期内的第一个 SMA(简单移动平均)作为初始值
同花顺 EMA:直接以第一根 K 线的收盘价作为初始 EMA 值
计算逻辑:
两者在后续递推计算上一致,均使用公式:
plaintext
EMA(今日) = (2/(周期+1)) × 收盘价(今日) + (1-2/(周期+1)) × EMA(昨日)
实际影响:
由于初始值不同,在计算初期(小于周期长度的 K 线数量时),两种方法结果差异较大;随着数据增多,差异会逐渐缩小。
使用时只需将你的收盘价数据整理成 pandas Series 格式,调用该函数即可得到与同花顺软件完全一致的 EMA 计算结果,便于策略回测和指标对比。
import pandas as pd
def tonghuashun_ema(close_series, period):
"""
按照同花顺的算法计算EMA指标
参数:
close_series: pd.Series,包含收盘价数据,索引为日期
period: int,EMA周期(如5、10、50等)
返回:
pd.Series,计算得到的EMA指标序列
"""
if len(close_series) < 1:
return pd.Series(dtype='float64')
# 平滑系数
alpha = 2 / (period + 1)
# 初始化EMA序列
ema = pd.Series(index=close_series.index, dtype='float64')
# 同花顺特色:第一根EMA值等于当日收盘价
ema.iloc[0] = close_series.iloc[0]
# 从第二根开始使用递推公式计算
for i in range(1, len(close_series)):
ema.iloc[i] = alpha * close_series.iloc[i] + (1 - alpha) * ema.iloc[i-1]
return ema
# 示例:计算同花顺EMA(12)和EMA(26)(常用的MACD组件)
if __name__ == "__main__":
import numpy as np
# 生成模拟数据(50个交易日收盘价)
dates = pd.date_range(start='2023-01-01', periods=50)
np.random.seed(42) # 固定随机种子,保证结果可复现
close_prices = np.cumsum(np.random.randn(50)) + 100 # 模拟价格波动
close_series = pd.Series(close_prices, index=dates, name='close')
# 计算同花顺EMA(12)和EMA(26)
ema12 = tonghuashun_ema(close_series, 12)
ema26 = tonghuashun_ema(close_series, 26)
# 合并结果并显示
result = pd.DataFrame({
'收盘价': close_series,
'EMA12(同花顺)': ema12,
'EMA26(同花顺)': ema26
})
print("同花顺EMA指标计算结果(前10行):")
print(result.head(10))
print("\n同花顺EMA指标计算结果(最后10行):")
print(result.tail(10))
然后直接把上面代码贴入ptrade,封装成函数,传入日线数据即可使用。
查看全部
初始值计算:
标准 EMA:以周期内的第一个 SMA(简单移动平均)作为初始值
同花顺 EMA:直接以第一根 K 线的收盘价作为初始 EMA 值
计算逻辑:
两者在后续递推计算上一致,均使用公式:
plaintext
EMA(今日) = (2/(周期+1)) × 收盘价(今日) + (1-2/(周期+1)) × EMA(昨日)
实际影响:
由于初始值不同,在计算初期(小于周期长度的 K 线数量时),两种方法结果差异较大;随着数据增多,差异会逐渐缩小。
使用时只需将你的收盘价数据整理成 pandas Series 格式,调用该函数即可得到与同花顺软件完全一致的 EMA 计算结果,便于策略回测和指标对比。
import pandas as pd
def tonghuashun_ema(close_series, period):
"""
按照同花顺的算法计算EMA指标
参数:
close_series: pd.Series,包含收盘价数据,索引为日期
period: int,EMA周期(如5、10、50等)
返回:
pd.Series,计算得到的EMA指标序列
"""
if len(close_series) < 1:
return pd.Series(dtype='float64')
# 平滑系数
alpha = 2 / (period + 1)
# 初始化EMA序列
ema = pd.Series(index=close_series.index, dtype='float64')
# 同花顺特色:第一根EMA值等于当日收盘价
ema.iloc[0] = close_series.iloc[0]
# 从第二根开始使用递推公式计算
for i in range(1, len(close_series)):
ema.iloc[i] = alpha * close_series.iloc[i] + (1 - alpha) * ema.iloc[i-1]
return ema
# 示例:计算同花顺EMA(12)和EMA(26)(常用的MACD组件)
if __name__ == "__main__":
import numpy as np
# 生成模拟数据(50个交易日收盘价)
dates = pd.date_range(start='2023-01-01', periods=50)
np.random.seed(42) # 固定随机种子,保证结果可复现
close_prices = np.cumsum(np.random.randn(50)) + 100 # 模拟价格波动
close_series = pd.Series(close_prices, index=dates, name='close')
# 计算同花顺EMA(12)和EMA(26)
ema12 = tonghuashun_ema(close_series, 12)
ema26 = tonghuashun_ema(close_series, 26)
# 合并结果并显示
result = pd.DataFrame({
'收盘价': close_series,
'EMA12(同花顺)': ema12,
'EMA26(同花顺)': ema26
})
print("同花顺EMA指标计算结果(前10行):")
print(result.head(10))
print("\n同花顺EMA指标计算结果(最后10行):")
print(result.tail(10))
然后直接把上面代码贴入ptrade,封装成函数,传入日线数据即可使用。
申万宏源 Ptrade / QMT/miniQMT 免5 开通
QMT • 李魔佛 发表了文章 • 0 个评论 • 3046 次浏览 • 2025-08-07 19:01
支持QMT,miniQMT和Ptrade。
量化功能应有尽有,是目前为止为数不多的有miniQMT的免5券商。
费率低,ETF,可转债均为万0.5
线上开户,需要的朋友可以扫码联系开通。
查看全部
ptrade获取集合竞价数据
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2677 次浏览 • 2025-08-07 18:48
date = '20250806'
stocks = ['300333.SZ']
data = get_trend_data(date=date, stocks=stocks)
# 返回数据
{'300333.SZ': {'time_stamp': 202508060930,
'hq_px': 14.1,
'wavg_px': 14.1,
'business_amount': 40300,
'business_balance': 568230,
'amount': 0}}
在实盘,回测,研究里面就能够使用
公众号:可转债量化分析
星球
查看全部
ptrade不同券商 数据质量 之 ETF数据质量残次不齐
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2749 次浏览 • 2025-07-23 18:28
etf_list = get_etf_list()
然后在不同的券商上运行。
国盛得到的数据:2025-07-23 16:07:15 - INFO - 公众号:可转债量化分析 ---- start ----
2025-07-23 16:08:00 - INFO - start func
2025-07-23 16:08:00 - INFO - 公众号:可转债量化分析
2025-07-23 16:08:00 - INFO - 660
得到的ETF数据有660只。
同样的代码,放到国金的ptrade上运行,得到 2025-07-23 15:45:10 - INFO - 当前服务器配置为:交易时间段服务器重启后,执行拉起本交易操作
2025-07-23 15:45:12 - INFO - 公众号:可转债量化分析 ---- start ----
2025-07-23 15:46:00 - INFO - start func
2025-07-23 15:46:00 - INFO - 公众号:可转债量化分析
2025-07-23 15:46:00 - INFO - 1043有1000只的ETF。
然后把日志导出到本地,用python求解一下不同的数据
(py11) D:\github\stock_strategy\api_validation>python etf-compare.py
516330.SS
561320.SS
159265.SZ
560980.SS
159813.SZ
159859.SZ
561700.SS
511620.SS
159898.SZ
159969.SZ
512380.SS
159972.SZ
159857.SZ
516300.SS
588200.SS
510180.SS
517520.SS
515680.SS
159618.SZ
159827.SZ
561980.SS
511820.SS
515150.SS
159701.SZ
159743.SZ
159623.SZ
159991.SZ
510660.SS
159681.SZ
159845.SZ
515890.SS
515850.SS
515300.SS
159510.SZ
511920.SS
159805.SZ
159610.SZ
159929.SZ
517170.SS
530800.SS
510630.SS
159535.SZ
561790.SS
159842.SZ
510150.SS
560580.SS
517800.SS
515790.SS
159806.SZ
516530.SS
159873.SZ
159207.SZ
515320.SS
516750.SS
159635.SZ
515290.SS
515030.SS
561130.SS
588150.SS
560680.SS
560280.SS
561570.SS
515760.SS
515900.SS
511090.SS
159643.SZ
588040.SS
159968.SZ
512520.SS
159322.SZ
516520.SS
159841.SZ
159359.SZ
515160.SS
511260.SS
516710.SS
159698.SZ
588230.SS
159786.SZ
562900.SS
159309.SZ
159358.SZ
563800.SS
159677.SZ
159551.SZ
517850.SS
159899.SZ
159862.SZ
159961.SZ
159779.SZ
515580.SS
159836.SZ
510060.SS
515010.SS
159355.SZ
560700.SS
159885.SZ
517880.SS
159864.SZ
159640.SZ
510270.SS
560150.SS
515750.SS
159003.SZ
159748.SZ
515330.SS
159730.SZ
159994.SZ
516290.SS
516080.SS
560510.SS
159005.SZ
159306.SZ
159378.SZ
512960.SS
159680.SZ
159847.SZ
159310.SZ
159587.SZ
588400.SS
515770.SS
159393.SZ
159657.SZ
516220.SS
159575.SZ
560350.SS
159997.SZ
515110.SS
159713.SZ
159880.SZ
159576.SZ
159520.SZ
562360.SS
588930.SS
518660.SS
159669.SZ
159206.SZ
159621.SZ
159928.SZ
159731.SZ
516050.SS
562390.SS
159831.SZ
516510.SS
159913.SZ
159633.SZ
511190.SS
512670.SS
516780.SS
517110.SS
159820.SZ
159690.SZ
159881.SZ
561230.SS
510010.SS
159992.SZ
159666.SZ
159725.SZ
159870.SZ
511010.SS
515060.SS
560860.SS
515100.SS
159993.SZ
512820.SS
159825.SZ
511900.SS
515990.SS
159849.SZ
563330.SS
512240.SS
159974.SZ
159910.SZ
159638.SZ
512890.SS
159641.SZ
159875.SZ
159682.SZ
159796.SZ
159887.SZ
159620.SZ
510880.SS
159225.SZ
159720.SZ
510410.SS
159883.SZ
159931.SZ
159363.SZ
588100.SS
561200.SS
560550.SS
159791.SZ
159229.SZ
159982.SZ
159647.SZ
560610.SS
159386.SZ
159559.SZ
159630.SZ
159795.SZ
511200.SS
512510.SS
561260.SS
159589.SZ
562860.SS
560090.SS
159889.SZ
159707.SZ
588320.SS
159678.SZ
510680.SS
159863.SZ
515980.SS
159543.SZ
510100.SS
159679.SZ
512040.SS
530000.SS
511770.SS
159838.SZ
159553.SZ
159998.SZ
515080.SS
588110.SS
561990.SS
159729.SZ
515120.SS
159739.SZ
159856.SZ
159800.SZ
510020.SS
510650.SS
159909.SZ
517550.SS
515630.SS
159685.SZ
515960.SS
515380.SS
561910.SS
515860.SS
518680.SS
588250.SS
159603.SZ
159339.SZ
159778.SZ
159958.SZ
516120.SS
588090.SS
159781.SZ
562300.SS
159761.SZ
517080.SS
159617.SZ
516060.SS
588680.SS
511580.SS
159521.SZ
159770.SZ
159397.SZ
159888.SZ
159816.SZ
516880.SS
159716.SZ
516910.SS
159209.SZ
588880.SS
562800.SS
515650.SS
561590.SS
159715.SZ
159552.SZ
512280.SS
588830.SS
516790.SS
159656.SZ
588460.SS
561350.SS
511850.SS
516830.SS
515530.SS
517120.SS
159658.SZ
563360.SS
517010.SS
516630.SS
159608.SZ
159959.SZ
563300.SS
563350.SS
516650.SS
561920.SS
561310.SS
516460.SS
512680.SS
159782.SZ
515360.SS
159628.SZ
159629.SZ
560260.SS
512730.SS
588010.SS
159697.SZ
588760.SS
513890.SS
159977.SZ
516500.SS
561500.SS
512220.SS
510550.SS
159555.SZ
588300.SS
530300.SS
159649.SZ
159395.SZ
560560.SS
516950.SS
511810.SS
561330.SS
159732.SZ
511600.SS
562890.SS
516550.SS
159717.SZ
159797.SZ
159970.SZ
561900.SS
561560.SS
159890.SZ
159721.SZ
560190.SS
159366.SZ
515950.SS
511950.SS
159908.SZ
159861.SZ
159517.SZ
159975.SZ
159625.SZ
159830.SZ
510050.SS
159895.SZ
517900.SS
159652.SZ
510990.SS
159811.SZ
159852.SZ
517000.SS
159930.SZ
159840.SZ
515070.SS
511670.SS
159807.SZ
561550.SS
511980.SS
159675.SZ
159611.SZ
560880.SS
515660.SS
560530.SS
511830.SS
159766.SZ
159631.SZ
561190.SS
512150.SS
561950.SS
517360.SS
518880.SS
510850.SS
159768.SZ
159876.SZ
159398.SZ
159865.SZ
515600.SS
159360.SZ
159305.SZ
511970.SS
159671.SZ
588310.SS
516770.SS
159320.SZ
516670.SS
517100.SS
159572.SZ
159839.SZ
159627.SZ
159665.SZ
159790.SZ
563520.SS
511520.SS
511690.SS
561160.SS
159723.SZ
159216.SZ
159886.SZ
510190.SS
159798.SZ
562590.SS
159843.SZ
159867.SZ
159663.SZ
159619.SZ
516090.SS
515090.SS
560080.SS
159869.SZ
159872.SZ
159736.SZ
560900.SS
588950.SS
159855.SZ
516150.SS
516960.SS
159828.SZ
517050.SS
159851.SZ
159645.SZ
511930.SS
159935.SZ
159703.SZ
517200.SS
512020.SS
159787.SZ
588240.SS
159362.SZ
517990.SS
561960.SS
562880.SS
159971.SZ
159760.SZ
159871.SZ
513630.SS
561380.SS
不同的ETF数量: 432这400多只的ETF是在国盛上缺失的。
这数据有点惊人.....
如果要用国盛,可以用国金的把ETF列表导出到txt,然后上传到国盛,然后在程序中读取这个etf列表。
查看全部
etf_list = get_etf_list()
然后在不同的券商上运行。
国盛得到的数据:
2025-07-23 16:07:15 - INFO - 公众号:可转债量化分析 ---- start ----
2025-07-23 16:08:00 - INFO - start func
2025-07-23 16:08:00 - INFO - 公众号:可转债量化分析
2025-07-23 16:08:00 - INFO - 660
得到的ETF数据有660只。
同样的代码,放到国金的ptrade上运行,得到
2025-07-23 15:45:10 - INFO - 当前服务器配置为:交易时间段服务器重启后,执行拉起本交易操作有1000只的ETF。
2025-07-23 15:45:12 - INFO - 公众号:可转债量化分析 ---- start ----
2025-07-23 15:46:00 - INFO - start func
2025-07-23 15:46:00 - INFO - 公众号:可转债量化分析
2025-07-23 15:46:00 - INFO - 1043
然后把日志导出到本地,用python求解一下不同的数据
这400多只的ETF是在国盛上缺失的。
(py11) D:\github\stock_strategy\api_validation>python etf-compare.py
516330.SS
561320.SS
159265.SZ
560980.SS
159813.SZ
159859.SZ
561700.SS
511620.SS
159898.SZ
159969.SZ
512380.SS
159972.SZ
159857.SZ
516300.SS
588200.SS
510180.SS
517520.SS
515680.SS
159618.SZ
159827.SZ
561980.SS
511820.SS
515150.SS
159701.SZ
159743.SZ
159623.SZ
159991.SZ
510660.SS
159681.SZ
159845.SZ
515890.SS
515850.SS
515300.SS
159510.SZ
511920.SS
159805.SZ
159610.SZ
159929.SZ
517170.SS
530800.SS
510630.SS
159535.SZ
561790.SS
159842.SZ
510150.SS
560580.SS
517800.SS
515790.SS
159806.SZ
516530.SS
159873.SZ
159207.SZ
515320.SS
516750.SS
159635.SZ
515290.SS
515030.SS
561130.SS
588150.SS
560680.SS
560280.SS
561570.SS
515760.SS
515900.SS
511090.SS
159643.SZ
588040.SS
159968.SZ
512520.SS
159322.SZ
516520.SS
159841.SZ
159359.SZ
515160.SS
511260.SS
516710.SS
159698.SZ
588230.SS
159786.SZ
562900.SS
159309.SZ
159358.SZ
563800.SS
159677.SZ
159551.SZ
517850.SS
159899.SZ
159862.SZ
159961.SZ
159779.SZ
515580.SS
159836.SZ
510060.SS
515010.SS
159355.SZ
560700.SS
159885.SZ
517880.SS
159864.SZ
159640.SZ
510270.SS
560150.SS
515750.SS
159003.SZ
159748.SZ
515330.SS
159730.SZ
159994.SZ
516290.SS
516080.SS
560510.SS
159005.SZ
159306.SZ
159378.SZ
512960.SS
159680.SZ
159847.SZ
159310.SZ
159587.SZ
588400.SS
515770.SS
159393.SZ
159657.SZ
516220.SS
159575.SZ
560350.SS
159997.SZ
515110.SS
159713.SZ
159880.SZ
159576.SZ
159520.SZ
562360.SS
588930.SS
518660.SS
159669.SZ
159206.SZ
159621.SZ
159928.SZ
159731.SZ
516050.SS
562390.SS
159831.SZ
516510.SS
159913.SZ
159633.SZ
511190.SS
512670.SS
516780.SS
517110.SS
159820.SZ
159690.SZ
159881.SZ
561230.SS
510010.SS
159992.SZ
159666.SZ
159725.SZ
159870.SZ
511010.SS
515060.SS
560860.SS
515100.SS
159993.SZ
512820.SS
159825.SZ
511900.SS
515990.SS
159849.SZ
563330.SS
512240.SS
159974.SZ
159910.SZ
159638.SZ
512890.SS
159641.SZ
159875.SZ
159682.SZ
159796.SZ
159887.SZ
159620.SZ
510880.SS
159225.SZ
159720.SZ
510410.SS
159883.SZ
159931.SZ
159363.SZ
588100.SS
561200.SS
560550.SS
159791.SZ
159229.SZ
159982.SZ
159647.SZ
560610.SS
159386.SZ
159559.SZ
159630.SZ
159795.SZ
511200.SS
512510.SS
561260.SS
159589.SZ
562860.SS
560090.SS
159889.SZ
159707.SZ
588320.SS
159678.SZ
510680.SS
159863.SZ
515980.SS
159543.SZ
510100.SS
159679.SZ
512040.SS
530000.SS
511770.SS
159838.SZ
159553.SZ
159998.SZ
515080.SS
588110.SS
561990.SS
159729.SZ
515120.SS
159739.SZ
159856.SZ
159800.SZ
510020.SS
510650.SS
159909.SZ
517550.SS
515630.SS
159685.SZ
515960.SS
515380.SS
561910.SS
515860.SS
518680.SS
588250.SS
159603.SZ
159339.SZ
159778.SZ
159958.SZ
516120.SS
588090.SS
159781.SZ
562300.SS
159761.SZ
517080.SS
159617.SZ
516060.SS
588680.SS
511580.SS
159521.SZ
159770.SZ
159397.SZ
159888.SZ
159816.SZ
516880.SS
159716.SZ
516910.SS
159209.SZ
588880.SS
562800.SS
515650.SS
561590.SS
159715.SZ
159552.SZ
512280.SS
588830.SS
516790.SS
159656.SZ
588460.SS
561350.SS
511850.SS
516830.SS
515530.SS
517120.SS
159658.SZ
563360.SS
517010.SS
516630.SS
159608.SZ
159959.SZ
563300.SS
563350.SS
516650.SS
561920.SS
561310.SS
516460.SS
512680.SS
159782.SZ
515360.SS
159628.SZ
159629.SZ
560260.SS
512730.SS
588010.SS
159697.SZ
588760.SS
513890.SS
159977.SZ
516500.SS
561500.SS
512220.SS
510550.SS
159555.SZ
588300.SS
530300.SS
159649.SZ
159395.SZ
560560.SS
516950.SS
511810.SS
561330.SS
159732.SZ
511600.SS
562890.SS
516550.SS
159717.SZ
159797.SZ
159970.SZ
561900.SS
561560.SS
159890.SZ
159721.SZ
560190.SS
159366.SZ
515950.SS
511950.SS
159908.SZ
159861.SZ
159517.SZ
159975.SZ
159625.SZ
159830.SZ
510050.SS
159895.SZ
517900.SS
159652.SZ
510990.SS
159811.SZ
159852.SZ
517000.SS
159930.SZ
159840.SZ
515070.SS
511670.SS
159807.SZ
561550.SS
511980.SS
159675.SZ
159611.SZ
560880.SS
515660.SS
560530.SS
511830.SS
159766.SZ
159631.SZ
561190.SS
512150.SS
561950.SS
517360.SS
518880.SS
510850.SS
159768.SZ
159876.SZ
159398.SZ
159865.SZ
515600.SS
159360.SZ
159305.SZ
511970.SS
159671.SZ
588310.SS
516770.SS
159320.SZ
516670.SS
517100.SS
159572.SZ
159839.SZ
159627.SZ
159665.SZ
159790.SZ
563520.SS
511520.SS
511690.SS
561160.SS
159723.SZ
159216.SZ
159886.SZ
510190.SS
159798.SZ
562590.SS
159843.SZ
159867.SZ
159663.SZ
159619.SZ
516090.SS
515090.SS
560080.SS
159869.SZ
159872.SZ
159736.SZ
560900.SS
588950.SS
159855.SZ
516150.SS
516960.SS
159828.SZ
517050.SS
159851.SZ
159645.SZ
511930.SS
159935.SZ
159703.SZ
517200.SS
512020.SS
159787.SZ
588240.SS
159362.SZ
517990.SS
561960.SS
562880.SS
159971.SZ
159760.SZ
159871.SZ
513630.SS
561380.SS
不同的ETF数量: 432
这数据有点惊人.....
如果要用国盛,可以用国金的把ETF列表导出到txt,然后上传到国盛,然后在程序中读取这个etf列表。
长江证券 ptrade 免五 开通门槛
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 3623 次浏览 • 2025-07-22 16:57
软件描述:长江证券PTrade交易终端是由恒生电子股份有限公司开发,为服务投资者专业化个性化交易需求而打造的交易终端
功能介绍:
1. 操作便捷:支持闪电下单、一键撤补、一键清仓、批量撤单、全键盘交易等功能
2. 功能丰富:提供策略交易、拐点交易、网格交易、抢单交易、追涨停、盘口扫单、可转债套利、ETF套利、篮子交易等交易工具
3. 量化交易:支持策略单交易,提供完整的策略平台,支持客户做策略研究、策略编写、策略回测和实盘交易
4. 极速交易:支持通过华锐ATP极速柜台、快速交易通道交易
MD5码:16ab7feba617b254c1607320ce69a780
版本:PTrade1.0-Client-V202308-15-000
文件大小:215.2M
文件名:PTrade1.0-Client-V202308-15-000_CY.zip
有2个版本,一个是长江证券ptrade交易终端(极速版),这个可以在上面编写python策略;
一个是Ptrade交易终端(简版),这个只提供了基础的量化工具,比如套利,网格,日内回转交易。不支持python编程功能。所以注意不要开错了哦。
下载链接:
https://downcq.95579.com/jcj/zg/PTrade1.0-Client-V202308-15-000_CY.zip
长期更新站点:
https://ptradeapi.com/
需要开通的朋友可以关注公众号联系: 查看全部
软件描述:长江证券PTrade交易终端是由恒生电子股份有限公司开发,为服务投资者专业化个性化交易需求而打造的交易终端
功能介绍:
1. 操作便捷:支持闪电下单、一键撤补、一键清仓、批量撤单、全键盘交易等功能
2. 功能丰富:提供策略交易、拐点交易、网格交易、抢单交易、追涨停、盘口扫单、可转债套利、ETF套利、篮子交易等交易工具
3. 量化交易:支持策略单交易,提供完整的策略平台,支持客户做策略研究、策略编写、策略回测和实盘交易
4. 极速交易:支持通过华锐ATP极速柜台、快速交易通道交易
MD5码:16ab7feba617b254c1607320ce69a780
版本:PTrade1.0-Client-V202308-15-000
文件大小:215.2M
文件名:PTrade1.0-Client-V202308-15-000_CY.zip
有2个版本,一个是长江证券ptrade交易终端(极速版),这个可以在上面编写python策略;
一个是Ptrade交易终端(简版),这个只提供了基础的量化工具,比如套利,网格,日内回转交易。不支持python编程功能。所以注意不要开错了哦。
下载链接:
https://downcq.95579.com/jcj/zg/PTrade1.0-Client-V202308-15-000_CY.zip
长期更新站点:
https://ptradeapi.com/
需要开通的朋友可以关注公众号联系:
聚宽小市值策略代码转Ptrade实盘代码
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 5465 次浏览 • 2025-07-05 22:35
Mark一下,写完之后分享一下。
聚宽的也不是完全的按照市值,也会根据换手率,涨停,跌停来判断是否卖出。
聚宽源码(部分)
#导入函数库
from jqdata import *
from jqfactor import *
import numpy as np
import pandas as pd
from datetime import time, datetime, timedelta
#初始化函数
def initialize(context):
# 策略参数配置
g.signal = ''
# 开启防未来函数
set_option('avoid_future_data', True)
# 设定基准
set_benchmark('000300.XSHG')
# 交易设置
set_option('use_real_price', True)
set_slippage(FixedSlippage(3/10000))
set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=2.5/10000, close_commission=2.5/10000, close_today_commission=0, min_commission=5), type='stock')
# 日志设置
log.set_level('order', 'error')
log.set_level('system', 'error')
log.set_level('strategy', 'debug')
# 策略控制参数
g.no_trading_today_signal = False # 是否为可交易日
g.pass_april = True # 是否四月空仓
g.run_stoploss = True # 是否进行止损
g.HV_control = False # 是否进行放量控制
g.HV_duration = 120 # 放量判断周期
g.HV_ratio = 0.9 # 放量判断比例
g.no_trading_hold_signal = False # 是否持有非交易期股票
# 持仓管理参数
g.hold_list = [] # 当前持仓的全部股票
g.yesterday_HL_list = [] # 记录持仓中昨日涨停的股票
g.target_list = [] # 目标买入列表
g.not_buy_again = [] # 不再买入的股票列表
# 交易参数
g.stock_num = 3 # 持仓数量
g.up_price = 100 # 最高买入价格
g.reason_to_sell = '' # 卖出原因
g.stoploss_strategy = 3 # 止损策略:1为止损线止损,2为市场趋势止损,3为联合策略
g.stoploss_limit = 0.91 # 个股止损线
g.stoploss_market = 0.95 # 市场趋势止损参数
g.no_trading_buy = ['600036.XSHG', '518880.XSHG', '600900.XSHG'] # 空仓月份持有
# 设置交易运行时间
run_daily(prepare_stock_list, '9:05')
run_weekly(weekly_adjustment, 2, '10:30')
run_daily(sell_stocks, time='10:00') # 止损函数
run_daily(trade_afternoon, time='14:25') # 检查持仓中的涨停股是否需要卖出
run_daily(trade_afternoon, time='14:55') # 检查持仓中的涨停股是否需要卖出
run_daily(close_account, '14:50')
转换后的Ptrade实盘源码(部分)
def before_trading_start(context, data):
log.info('================= 盘前运行开始:{} '.format(str(context.blotter.current_dt)))
g.__portfolio = PositionManager()
g.order_set = set()
# g.__lock = threading.Lock()
def remove_st_stock(all_stock_list):
st_dict = get_stock_status(all_stock_list, query_type='ST', query_date=None)
st_list = []
for k, v in st_dict.items():
if v:
st_list.append(k)
return st_list
def remove_halt_stock(all_stock_list):
halt_dict = get_stock_status(all_stock_list, query_type='HALT', query_date=None)
halt_list = []
for k, v in halt_dict.items():
if v:
halt_list.append(k)
return halt_list
def all_codes_in_market():
all_stock_set = set(get_Ashares(date=None))
for ignore_code in IGNORE_MARKET:
market = MARKET_DICT.get(ignore_code)
if market == '科创板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('68'), all_stock_set))
if market == '创业板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('3'), all_stock_set))
return all_stock_set
待续 查看全部
Mark一下,写完之后分享一下。
聚宽的也不是完全的按照市值,也会根据换手率,涨停,跌停来判断是否卖出。
聚宽源码(部分)
#导入函数库
from jqdata import *
from jqfactor import *
import numpy as np
import pandas as pd
from datetime import time, datetime, timedelta
#初始化函数
def initialize(context):
# 策略参数配置
g.signal = ''
# 开启防未来函数
set_option('avoid_future_data', True)
# 设定基准
set_benchmark('000300.XSHG')
# 交易设置
set_option('use_real_price', True)
set_slippage(FixedSlippage(3/10000))
set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=2.5/10000, close_commission=2.5/10000, close_today_commission=0, min_commission=5), type='stock')
# 日志设置
log.set_level('order', 'error')
log.set_level('system', 'error')
log.set_level('strategy', 'debug')
# 策略控制参数
g.no_trading_today_signal = False # 是否为可交易日
g.pass_april = True # 是否四月空仓
g.run_stoploss = True # 是否进行止损
g.HV_control = False # 是否进行放量控制
g.HV_duration = 120 # 放量判断周期
g.HV_ratio = 0.9 # 放量判断比例
g.no_trading_hold_signal = False # 是否持有非交易期股票
# 持仓管理参数
g.hold_list = [] # 当前持仓的全部股票
g.yesterday_HL_list = [] # 记录持仓中昨日涨停的股票
g.target_list = [] # 目标买入列表
g.not_buy_again = [] # 不再买入的股票列表
# 交易参数
g.stock_num = 3 # 持仓数量
g.up_price = 100 # 最高买入价格
g.reason_to_sell = '' # 卖出原因
g.stoploss_strategy = 3 # 止损策略:1为止损线止损,2为市场趋势止损,3为联合策略
g.stoploss_limit = 0.91 # 个股止损线
g.stoploss_market = 0.95 # 市场趋势止损参数
g.no_trading_buy = ['600036.XSHG', '518880.XSHG', '600900.XSHG'] # 空仓月份持有
# 设置交易运行时间
run_daily(prepare_stock_list, '9:05')
run_weekly(weekly_adjustment, 2, '10:30')
run_daily(sell_stocks, time='10:00') # 止损函数
run_daily(trade_afternoon, time='14:25') # 检查持仓中的涨停股是否需要卖出
run_daily(trade_afternoon, time='14:55') # 检查持仓中的涨停股是否需要卖出
run_daily(close_account, '14:50')
转换后的Ptrade实盘源码(部分)
def before_trading_start(context, data):
log.info('================= 盘前运行开始:{} '.format(str(context.blotter.current_dt)))
g.__portfolio = PositionManager()
g.order_set = set()
# g.__lock = threading.Lock()
def remove_st_stock(all_stock_list):
st_dict = get_stock_status(all_stock_list, query_type='ST', query_date=None)
st_list = []
for k, v in st_dict.items():
if v:
st_list.append(k)
return st_list
def remove_halt_stock(all_stock_list):
halt_dict = get_stock_status(all_stock_list, query_type='HALT', query_date=None)
halt_list = []
for k, v in halt_dict.items():
if v:
halt_list.append(k)
return halt_list
def all_codes_in_market():
all_stock_set = set(get_Ashares(date=None))
for ignore_code in IGNORE_MARKET:
market = MARKET_DICT.get(ignore_code)
if market == '科创板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('68'), all_stock_set))
if market == '创业板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('3'), all_stock_set))
return all_stock_set
待续
国盛Ptrade get_Ashare函数返回为空
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2431 次浏览 • 2025-07-04 12:22
在实盘中,运行下面代码:
# author: 公众号:可转债量化分析
import datetime
def initialize(context):
# 初始化策略
pass
def before_trading_start(context, data):
log.info('盘前函数运行')
previous_tradeing_func(context) # 执行盘前函数
def previous_tradeing_func(context):
all_stock_set = get_Ashares(date=None)
print(all_stock_set)
def handle_data(context, data):
pass
运行结果:
2025-07-04 12:18:10 - INFO - 盘前函数运行
2025-07-04 12:18:10 - INFO - []
数据的是一个空的list.......
一个十分基础的数据。
反馈了几年,依然如是。。
还是多开几家,多对比。各有各的优势。 查看全部
在实盘中,运行下面代码:
# author: 公众号:可转债量化分析
import datetime
def initialize(context):
# 初始化策略
pass
def before_trading_start(context, data):
log.info('盘前函数运行')
previous_tradeing_func(context) # 执行盘前函数
def previous_tradeing_func(context):
all_stock_set = get_Ashares(date=None)
print(all_stock_set)
def handle_data(context, data):
pass
运行结果:
2025-07-04 12:18:10 - INFO - 盘前函数运行
2025-07-04 12:18:10 - INFO - []
数据的是一个空的list.......
一个十分基础的数据。
反馈了几年,依然如是。。
还是多开几家,多对比。各有各的优势。
谁说ptrade代码不安全容易泄露的?
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 3372 次浏览 • 2025-07-03 11:52
实际上现在的ptrade可以对策略进行加密
可以对你的策略进行加密下载,然后把策略删除了,然后在选择上传策略。
然后策略上传之后,你是无法看到具体代码的了,只能选择启动,删除策略。
连日志里面的打印数据也不会输出。
只会显示买入 卖出 的信息。
大大的提高了策略的安全性。
需要开通ptrade的读者朋友,可以关注公众号联系:
低佣 - 低门槛,提供 技术支持
查看全部
ptrade查看日志报错:远程服务器返回错误: (502) 错误的网关
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2336 次浏览 • 2025-06-30 18:59
访问这个API的时候就已经报错。
502异常代码,是服务器端的报错。和本地无关。
有时候能够正常查询到日志,但大部分时候查询日志的时候就出现上面的502异常。
揪心,就不能买多几台服务器么.....
查看全部
Ptrade获取的L2逐笔数据和同花顺的逐笔数据对不上的原因
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 2757 次浏览 • 2025-06-12 16:40
后面有群友 发现了问题。
QMT股票两融对冲建仓实盘
QMT • 李魔佛 发表了文章 • 0 个评论 • 3537 次浏览 • 2024-05-29 12:02
成交了多少量,就融券多少量。达到指标即可停止。
代写量化程序,可以关注公众号,后台联系。 价格比QMT官网低的多了。实战性选手,选过N多QMT,ptrade实盘代码。
查看全部
QMT实时获取涨停股,筛选流通盘大于X的股票
QMT • 李魔佛 发表了文章 • 0 个评论 • 4994 次浏览 • 2024-02-07 18:28
直接上代码:# 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)}秒')
欢迎关注公众号:
可转债量化分析 查看全部
直接上代码:
# 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)}秒')
欢迎关注公众号:
可转债量化分析
QMT | Ptrade 量化策略代写服务
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 5433 次浏览 • 2023-11-01 10:43
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:
查看全部
迅投的QMT和恒生电子的Ptrade, 还有掘金, 量化策略编程, 实盘和回测都行。只要你的需求明确,白纸黑字描述清楚,都可以做。股票,ETF,可转债都行。
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:

小市值轮动-量化交易-程序化交易-Ptrade实盘
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 5137 次浏览 • 2023-10-07 14:14
当前策略持有30只。
点击查看大图
点击查看大图
基于股票的策略不敢多买,属于试验阶段,后期仍然会不断根据市场调仓; 主仓依然在可转债。
公众号:可转债量化分析
如果需要策略代写,(ptrade、qmt,其他量化平台)
可以公众号后台回复:
策略代写
查看全部
ptrade qmt无法登录问题
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 5031 次浏览 • 2023-08-08 14:44
实际上这是在周五晚上和周末出现的问题,这是计划内的维护。部分券商没有技术服务支持,用户可能连服务器日常维护服务通知都无法及时得到通知。
PS:其实,大部分券商基本也就那样,ptrade和qmt的技术支持基本等于0,不敢说全部,至少90%的情况是这样的。 以至于我自己维护了一个ptrade,qmt的技术群(审核才可以加),日常有空就在里面解决群友的问题。基本都是些基础问题,部分可能是券商数据问题,大部分是用户的代码问题。 查看全部
ptrade批量获取股票的昨天的收盘价,转为字典json【一】
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 5703 次浏览 • 2023-07-17 19:50
ptrade接口文档:https://ptradeapi.com
笔者这里接写几个最简单的方式,供读者朋友参考。
下面代码适用于实盘,回测。
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
yesterday_price_dict = zz_df_price.iloc[0].to_json()
讲解:
1.
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的,比如你可以先拿沪深300指数的成分股,然后传入这个函数。
2.
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
get_price: 获取历史数据。 这里不用get_history,因为这个函数太多bug了,主要是券商数据可能是缺的。拿历史数据我基本不敢用get_history。
因为我拿昨天的收盘价,所以我就不指定日期,只用count=1,获取1条数据,因为数据是从最新开始的,那么这一条数据肯定是上一个交易日的。
正常情况返回的数据是一个Pannel,三维的。不过因为filed=‘close',单个字段,特殊情况,这里返回的是一个dataframe
输出:
zz_df_price.iloc[0].to_json()
index 113578.SS 123014.SZ
2023-07-14 93.036 118.36
所以接下来要做的是,获取dataframe的第一行数据,直接转为json
得到:
'{"113578.SS":93.036,"123014.SZ":118.36}'
更多技术支持与解答,欢迎加入星球。
查看全部
ptrade接口文档:https://ptradeapi.com
笔者这里接写几个最简单的方式,供读者朋友参考。
下面代码适用于实盘,回测。
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
yesterday_price_dict = zz_df_price.iloc[0].to_json()
讲解:
1.
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的,比如你可以先拿沪深300指数的成分股,然后传入这个函数。
2.
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
get_price: 获取历史数据。 这里不用get_history,因为这个函数太多bug了,主要是券商数据可能是缺的。拿历史数据我基本不敢用get_history。
因为我拿昨天的收盘价,所以我就不指定日期,只用count=1,获取1条数据,因为数据是从最新开始的,那么这一条数据肯定是上一个交易日的。
正常情况返回的数据是一个Pannel,三维的。不过因为filed=‘close',单个字段,特殊情况,这里返回的是一个dataframe
输出:
zz_df_price.iloc[0].to_json()index 113578.SS 123014.SZ
2023-07-14 93.036 118.36
所以接下来要做的是,获取dataframe的第一行数据,直接转为json
得到:
'{"113578.SS":93.036,"123014.SZ":118.36}'
更多技术支持与解答,欢迎加入星球。

目前支持量化接口的万一免五的券商有哪些?
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 8457 次浏览 • 2023-07-04 22:52
其中能够股票免五的有国金证券,国盛证券,国信证券,安信证券。
其中,国金证券,国盛证券支持QMT、MiniQMT、Ptrade。
国信证券,安信证券支持QMT。
东莞证券支持Ptrade
可转债默认免五。
开户后可加入量化技术交流群,可获得编程技术指导。
【提问者需要把问题描述清楚即可,PS: 有些人动不动就说:“Ptrade不行呀”,“QMT垃圾呀”,结果让他贴代码上来瞅瞅,是他本身代码写的拉垮,目前贴出来的已知的问题,90%是个人代码问题。】
扫码添加微信咨询开户:
查看全部
Ptrade/QMT 可转债转股操作 python代码
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 5656 次浏览 • 2023-06-19 18:14
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号
查看全部
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号

国金证券QMT量化新人培训教程
QMT • 李魔佛 发表了文章 • 0 个评论 • 10801 次浏览 • 2023-05-29 00:37
视频已经整理放到B站:
https://space.bilibili.com/73827743/channel/seriesdetail?sid=3326385&ctype=0
视频目录:
量化新人用QMT+chat GPT快速上手量化策略(一)QMT基础介绍
量化新人用QMT+chat GPT快速上手量化策略(二)QMT均线盘后选股
量化新人用QMT+chat GPT快速上手量化策略(三)一个基本的回测策略代码
量化新人用QMT+chat GPT快速上手量化策略(四) QMT运行一个策略的整体流程
量化新人用QMT+chat GPT快速上手量化策略(五) 获取股票数据
量化新人用QMT+chat GPT快速上手量化策略(六) tablib计算指标
量化新人用QMT+chat GPT快速上手量化策略(七) 下单代码编写
欢迎观看并提出疑问。
公众号:可转债量化分析 查看全部
视频已经整理放到B站:
https://space.bilibili.com/73827743/channel/seriesdetail?sid=3326385&ctype=0
视频目录:
量化新人用QMT+chat GPT快速上手量化策略(一)QMT基础介绍
量化新人用QMT+chat GPT快速上手量化策略(二)QMT均线盘后选股
量化新人用QMT+chat GPT快速上手量化策略(三)一个基本的回测策略代码
量化新人用QMT+chat GPT快速上手量化策略(四) QMT运行一个策略的整体流程
量化新人用QMT+chat GPT快速上手量化策略(五) 获取股票数据
量化新人用QMT+chat GPT快速上手量化策略(六) tablib计算指标
量化新人用QMT+chat GPT快速上手量化策略(七) 下单代码编写
欢迎观看并提出疑问。
公众号:可转债量化分析
用户问的比较多的关于ptrade基础问题
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 6595 次浏览 • 2023-05-04 01:19
1. 国金的Ptrade 实盘交易客户端是无法进行回测的,在任何时间段;
而模拟客户端可以,可以找自己的经理申请一个Ptrade模拟客户端账户;
2. 国盛的Ptrade实盘交易客户端仅在交易时间无法回测,但非交易时间可以回测;
主要是因为实盘回测和交易在同一个服务器,回测占用过多资源会影响实盘交易;模拟客户端没有这个问题;
任何时间段均可以回测; (之前某个券商的ptrade实盘服务器,因为某个用户开了40多个回测策略,一直在后台运行,而且是关于运算密集型的,导致实盘交易的程序也崩溃了)
3. 国金Ptrade无法回测星球上面的可转债实盘代码,实盘代码是基于当前的实时数据,用来进行回测没有意义,因为获取不到可转债的历史数据(溢价率,规模等),只有历史的价格数据;
4. 国金Ptrade无法使用星球上的可转债代码进行实盘,因为无法访问外网,无法访问我部署的接口数据; 而国盛的Ptrade可以;如果国金Ptrade需要实盘交易可转债,需要手工上传一些基础数据,Ptrade提供上传功能,具体操作可查找星球相关文章;
5. 在共享的Ptrade模拟试用账户上,不要保留个人代码记录,跑完后记得删除,否则其他共有同一个账户的人可以进去修改复制你的策略和代码;如果是单独的个人模拟账户,则没有这个问题。
查看全部
1. 国金的Ptrade 实盘交易客户端是无法进行回测的,在任何时间段;
而模拟客户端可以,可以找自己的经理申请一个Ptrade模拟客户端账户;
2. 国盛的Ptrade实盘交易客户端仅在交易时间无法回测,但非交易时间可以回测;
主要是因为实盘回测和交易在同一个服务器,回测占用过多资源会影响实盘交易;模拟客户端没有这个问题;
任何时间段均可以回测; (之前某个券商的ptrade实盘服务器,因为某个用户开了40多个回测策略,一直在后台运行,而且是关于运算密集型的,导致实盘交易的程序也崩溃了)
3. 国金Ptrade无法回测星球上面的可转债实盘代码,实盘代码是基于当前的实时数据,用来进行回测没有意义,因为获取不到可转债的历史数据(溢价率,规模等),只有历史的价格数据;
4. 国金Ptrade无法使用星球上的可转债代码进行实盘,因为无法访问外网,无法访问我部署的接口数据; 而国盛的Ptrade可以;如果国金Ptrade需要实盘交易可转债,需要手工上传一些基础数据,Ptrade提供上传功能,具体操作可查找星球相关文章;
5. 在共享的Ptrade模拟试用账户上,不要保留个人代码记录,跑完后记得删除,否则其他共有同一个账户的人可以进去修改复制你的策略和代码;如果是单独的个人模拟账户,则没有这个问题。
Ptrade QMT实盘策略记录 - 不定期更新
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 4495 次浏览 • 2023-04-03 15:27
写出来的是已经实现且实盘稳定运行的;
涨停板;依赖ptrade的高速行情自动配合手动;两融账户的股票日内做T,持有底仓;股票小市值轮动+多因子可转债多因子(有N个版本+不同的排除因子 组合)可转债日内高频股票趋势动量ETF轮动套利脉冲卖出扫描
纯粹自己做的记录,便于自己平时复盘。
有兴趣的朋友可以关注公众号交流。 查看全部
Ptrade担保品买入卖出
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 3301 次浏览 • 2023-03-31 01:31
实际上是买卖股票,但在信用账户上,用只有资金买卖股票。
ptrade支持两融操作。
比如下面的示例代告诉我们,担保品买入股票的3个不同参数的效果:def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 以系统最新价委托
margin_trade(g.security, 100)
# 以72块价格下一个限价单
margin_trade(g.security, 100, limit_price=72)
# 以最优五档即时成交剩余撤销委托
margin_trade(g.security, 200, market_type=4) security:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int);
limit_price:买卖限价(float);
market_type:市价委托类型,上证非科创板股票支持参数1、4,上证科创板股票支持参数0、1、2、4,深证股票支持参数0、2、3、4、5(int);
0:对手方最优价格;
1:最优五档即时成交剩余转限价;
2:本方最优价格;
3:即时成交剩余撤销;
4:最优五档即时成交剩余撤销;
5:全额成交或撤单; 查看全部
担保品卖出指的是融资融券交易当中,用自有资金进行买卖的行为
实际上是买卖股票,但在信用账户上,用只有资金买卖股票。
ptrade支持两融操作。
比如下面的示例代告诉我们,担保品买入股票的3个不同参数的效果:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 以系统最新价委托
margin_trade(g.security, 100)
# 以72块价格下一个限价单
margin_trade(g.security, 100, limit_price=72)
# 以最优五档即时成交剩余撤销委托
margin_trade(g.security, 200, market_type=4)
security:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int);
limit_price:买卖限价(float);
market_type:市价委托类型,上证非科创板股票支持参数1、4,上证科创板股票支持参数0、1、2、4,深证股票支持参数0、2、3、4、5(int);
0:对手方最优价格;
1:最优五档即时成交剩余转限价;
2:本方最优价格;
3:即时成交剩余撤销;
4:最优五档即时成交剩余撤销;
5:全额成交或撤单;
qmt 可转债 双低(阈值)轮动 实盘代码
QMT • 李魔佛 发表了文章 • 0 个评论 • 4857 次浏览 • 2023-02-26 15:18
用已有的ptrade的代码,然后部分获取行情和交易接口按照qmt的接口文档(http://qmt.ptradeapi.com )重写,就给了一版。(对,很早以前就有一版ptrade的转债双低的了)
无论是qmt还是ptrade,都只是一个工具,用熟悉了,都无所哪个好哪个不好。
完整代码在个人星球。
觉得之前星球太便宜了,不仅给了代码,还部署了接口免费使用,通过接口获取可转债的实时数据,强赎天数,规模,溢价率,评级等等一系列数据。 而且随着时间的推移,里面积累的数据,代码也越来越多,感觉这样对前面进去并不断续费的星友有点公平,尽管以后他们续费都直接打折扣。所以还是按照一些大v运营的意见,逐年涨价策略。
越往后的朋友,因为前面积累的内容越多,因此价格也随之增长。
当然有能力可以自己写接口,部署,实盘,获取三方数据的大v,就没必要加了。
查看全部
用已有的ptrade的代码,然后部分获取行情和交易接口按照qmt的接口文档(http://qmt.ptradeapi.com )重写,就给了一版。(对,很早以前就有一版ptrade的转债双低的了)
无论是qmt还是ptrade,都只是一个工具,用熟悉了,都无所哪个好哪个不好。
完整代码在个人星球。
觉得之前星球太便宜了,不仅给了代码,还部署了接口免费使用,通过接口获取可转债的实时数据,强赎天数,规模,溢价率,评级等等一系列数据。 而且随着时间的推移,里面积累的数据,代码也越来越多,感觉这样对前面进去并不断续费的星友有点公平,尽管以后他们续费都直接打折扣。所以还是按照一些大v运营的意见,逐年涨价策略。
越往后的朋友,因为前面积累的内容越多,因此价格也随之增长。
当然有能力可以自己写接口,部署,实盘,获取三方数据的大v,就没必要加了。
qmt iquant最新接口文档
QMT • 李魔佛 发表了文章 • 0 个评论 • 3574 次浏览 • 2023-02-19 15:16
http://qmt.ptradeapi.com
除了官方的接口文档,还加入了一些个人平时编写的写法与回测,实盘代码。 不定期更新。
欢迎关注收藏。 查看全部
http://qmt.ptradeapi.com
除了官方的接口文档,还加入了一些个人平时编写的写法与回测,实盘代码。 不定期更新。
欢迎关注收藏。
迅投qmt入门教程(一)
QMT • 李魔佛 发表了文章 • 0 个评论 • 26764 次浏览 • 2023-02-06 19:43
1. 准备:
首先得开一个支持qmt的券商,目前市面上支持qmt的券商越来越丰富了。
初学者可以开一个门槛第一点的,一般入金1w-2w 不等,就可以申请开通了。
鉴于以学习为目的,真正投入到实盘中的资金不会很大,所以初始阶段也不一定就找万一免五的券商,毕竟目前要给免五,资金门槛比较高,一般要100w甚至以上。
笔者推荐国信,国金的qmt, 门槛只要1-2w就足够了,股票费率在万一,可转债万0.4-万0.5。适合初学者,这两家也可以在虚拟机运行,适合苹果mac的用户。 需要的朋友也可以在公众号后台留言: qmt开通
2. 假设已经在券商那里开通了qmt功能,接下来就开始进入教学:
这里以国信的qmt(iquant)为例:
首先要做的就是下载python库。 这个python库指的是qmt的python库,它的版本是3.6.8; 如果你只用qmt内置的python,你就不用自己到网上下载python安装程序,只需要在qmt的设置里面,点一下按钮,就可以安装python库。这里用默认的系统路径就可以了。
3. 第一个量化程序 hello world
新建策略后:
在编辑器里面输入下面的代码:#encoding:gbk
def init(ContextInfo):
print('hello world')
def handlebar(ContextInfo):
#计算当前主图的cci
print("handle bar")
点击回测:
得到输出结果
这里介绍2个概念:(3)Handlebar
handlebar 是整个 Python 模型中的核心执行函数。当模型从数据层获取到运行所需要的数据之后,会对数据集上的每一根 bar,调用一次 handlebar 函数,处理当前这根 bar 上的数据。也就是说,用户模型的核心逻辑都是写在该函数中的,如获取数据,设置下单条件等。在 handlebar 中处理完数据后,用户可以通过 paint 方法将需要绘图输出的结果返回给界面。界面会将输出结果如实的展示出来。 (4)ContextInfo
ContextInfo 是整个 Python 框架中的一个核心对象。它包含了各种与 Python 底层框架交互的 API 方法,也是一个全局的上下文环境,可以在 init 以及 handlebar 这两个函数中自由地传递用户创建的各种自定义数据。
文绉绉的,实际写一个策略,必须包含下面两个函数,而且参数也要一致,参数名随意,不过用默认的就好了。你随便改成没有意义的字符,后面自己看代码也是很麻烦。def init(ContextInfo):
pass
def handlebar(ContextInfo):
pass
init 和 handlebar 是 Python 模型中最重要的方法,也是唯二由 C++ 直接调用的方法,所有的执行代码都尽量写在这两个方法中或由其中的函数调用。【个人不太喜欢这样】
回测时间设置,在右边的菜单栏,有个回测参数,里面设置时间;在菜单“基本信息”里面 ,可以设置回测的时间间隔,可以使用分钟线,日线,小时等等不同周期,不过无法做到tick的回测。最小的只能到分钟。
但是如果你有秒的tick数据,自己写个回测框架也是可以做到秒级的tick级别的回测。很早前笔者就在星球上提供了完整的源码和数据,初学者也可以拿着去改,只要后续更新tick数据,就可以不断的回测策略的最新状态。
你写的回测实盘python代码,是保存在本地的文件夹的:
C:\iquant_gx\python, 前面的C:\iquant_gx 是你的iquant安装路径。
而且底下也有很多的现成的代码:
部分代码可以直接用pycharm就可以打开,没有加密的,但也有一些是加密了的。
比如这个自动逆回购是现成的:
对,这里就有,很多人还到处找人写;# encoding:gbk
import logging
from datetime import datetime, timedelta
from decimal import Decimal as D
from decimal import InvalidOperation
logging.basicConfig(level=logging.INFO)
# 挂单失败后的等待时长,以秒计
TIMEOUT_ON_FAIL_SEC = 30
# 等待account_callback的时长
# RUN_TIME_DELAY = 30
# how is this not defined in package??
MORNING_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '093000', '%Y%m%d%H%M%S')
MORNING_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '113000', '%Y%m%d%H%M%S')
NOON_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '130000', '%Y%m%d%H%M%S')
NOON_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '153000', '%Y%m%d%H%M%S')
# for SH only
TRANS_COST_1D = D('5e-6')
TRANS_COST_LONG = D('1.5e-7')
TRANS_COST_MAX = 100
# ORDER LIMITS
SH_UPPER = 1e7
SH_LOWER = 1e5
SZ_UPPER = 1e8
SZ_LOWER = 1e3
# ASSET NAME DICT
SH_REV_REPO = {'上交所1天': '204001.SH', '上交所2天': '204002.SH', '上交所3天': '204003.SH',
'上交所4天': '204004.SH', '上交所7天': '204007.SH', '上交所14天': '204014.SH',
'上交所28天': '204028.SH', '上交所91天': '204091.SH', '上交所182天': '204182.SH',
}
SZ_REV_REPO = {'深交所3天': '131800.SZ', '深交所7天': '131801.SZ', '深交所14天': '131802.SZ',
'深交所28天': '131803.SZ', '深交所91天': '131805.SZ', '深交所182天': '131806.SZ',
'深交所4天': '131809.SZ', '深交所1天': '131810.SZ', '深交所2天': '131811.SZ',
}
def init(ContextInfo):
ContextInfo.accID = account
ContextInfo.set_account(ContextInfo.accID)
ContextInfo.use_all_cap = False if ALL_CAP == '否' else True
# global trading control, set to False if detected error on user's side
# stop() does not halt strat
ContextInfo.order_control = False
if not ContextInfo.use_all_cap:
try:
ContextInfo.dollar_vol = float(D(DOLLAR_VOL))
except InvalidOperation:
ContextInfo.order_control = True
raise ValueError('读取资金量失败')
else:
if DOLLAR_VOL != '':
logging.warning('已设定使用全部账户资金,忽略所设置资金量')
try:
ContextInfo.start_time = datetime.strptime(datetime.now().strftime('%Y%m%d') + str(START_TIME), '%Y%m%d%H%M%S')
ContextInfo.asset_name = SH_REV_REPO[ASSET_NAME]
except KeyError:
ContextInfo.asset_name = SZ_REV_REPO[ASSET_NAME]
except ValueError as error:
if 'unconverted data remains' in str(error):
ContextInfo.order_control = True
raise ValueError('读取挂单时间失败')
if not (MORNING_END > ContextInfo.start_time >= MORNING_START) \
and not (NOON_END > ContextInfo.start_time >= NOON_START):
ContextInfo.order_control = True
raise ValueError('挂单时间不在可交易时间内')
ContextInfo.can_order = False
ContextInfo.order_done = False
if not ContextInfo.order_control:
ContextInfo.run_time("place_order", "{0}nSecond".format(TIMEOUT_ON_FAIL_SEC),
ContextInfo.start_time.strftime('%Y-%m-%d %H:%M:%S'), 'SH')
def account_callback(ContextInfo, accountInfo):
if not ContextInfo.can_order:
ContextInfo.can_order = True
if ContextInfo.use_all_cap:
ContextInfo.dollar_vol = accountInfo.m_dAvailable
else:
if ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('下单额度大于账户可用资金')
# check if order satisfies lower limit for each exchange
if ('SH' in ContextInfo.asset_name and ContextInfo.dollar_vol < SH_LOWER) \
or ('SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol < SZ_LOWER):
ContextInfo.order_control = True
raise ValueError('下单额度低于交易所最低限额')
# checks dollar_vol and rounds the total amount
if 'SH' in ContextInfo.asset_name and ContextInfo.dollar_vol % SH_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SH_LOWER) * SH_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
elif 'SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol % SZ_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SZ_LOWER) * SZ_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
'''
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.dollar_vol // SH_UPPER)
remain_order = ContextInfo.dollar_vol - num_batch_order * SH_UPPER
if ContextInfo.asset_name == '204001.SH':
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_1D
else:
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_LONG
if transaction_cost + ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('可用资金不足以垫付交易金额与手续费')
'''
ContextInfo.remain_vol = ContextInfo.dollar_vol
def handlebar(ContextInfo):
return
def place_order(ContextInfo):
if not ContextInfo.can_order or ContextInfo.order_control:
return
if not ContextInfo.order_done:
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.remain_vol // SH_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SH_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SH_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SH_UPPER, order_remark, 1,
order_remark, ContextInfo)
else:
num_batch_order = int(ContextInfo.remain_vol // SZ_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SZ_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SZ_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SZ_UPPER, order_remark, 1,
order_remark, ContextInfo)
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(remain_order, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, remain_order, order_remark, 1,
order_remark, ContextInfo)
ContextInfo.remain_vol = 0
ContextInfo.order_done = True
def order_callback(ContextInfo, orderInfo):
curr_remark = orderInfo.m_strRemark
curr_status = orderInfo.m_nOrderStatus
if '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 57:
ContextInfo.order_done = False
# up the leftover dollar vol by failed amount
# logging.info('reported trade amount:{0}, reported_trade_volume:{1}'.format(orderInfo.m_dTradeAmount, orderInfo.m_nVolumeTotal))
# 单张100元
ContextInfo.remain_vol += orderInfo.m_nVolumeTotal * 100
if '交易时间不合法' in orderInfo.m_strCancelInfo:
ContextInfo.order_control = True
raise ValueError('国债逆回购:未能在交易时间内完成下单,停止报单。余量{0}元未报'.format(ContextInfo.remain_vol))
logging.warning('国债逆回购:报单废单,原因:\"{0}\",尝试重报'.format(orderInfo.m_strCancelInfo))
elif '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 50:
logging.info('国债逆回购:报单{0}元成功'.format(orderInfo.m_nVolumeTotal * 100))
return
待续,不定期更新
公众号:
星球:
查看全部
1. 准备:
首先得开一个支持qmt的券商,目前市面上支持qmt的券商越来越丰富了。
初学者可以开一个门槛第一点的,一般入金1w-2w 不等,就可以申请开通了。
鉴于以学习为目的,真正投入到实盘中的资金不会很大,所以初始阶段也不一定就找万一免五的券商,毕竟目前要给免五,资金门槛比较高,一般要100w甚至以上。
笔者推荐国信,国金的qmt, 门槛只要1-2w就足够了,股票费率在万一,可转债万0.4-万0.5。适合初学者,这两家也可以在虚拟机运行,适合苹果mac的用户。 需要的朋友也可以在公众号后台留言: qmt开通
2. 假设已经在券商那里开通了qmt功能,接下来就开始进入教学:
这里以国信的qmt(iquant)为例:
首先要做的就是下载python库。 这个python库指的是qmt的python库,它的版本是3.6.8; 如果你只用qmt内置的python,你就不用自己到网上下载python安装程序,只需要在qmt的设置里面,点一下按钮,就可以安装python库。这里用默认的系统路径就可以了。
3. 第一个量化程序 hello world
新建策略后:
在编辑器里面输入下面的代码:
#encoding:gbk
def init(ContextInfo):
print('hello world')
def handlebar(ContextInfo):
#计算当前主图的cci
print("handle bar")
点击回测:
得到输出结果
这里介绍2个概念:
(3)Handlebar
handlebar 是整个 Python 模型中的核心执行函数。当模型从数据层获取到运行所需要的数据之后,会对数据集上的每一根 bar,调用一次 handlebar 函数,处理当前这根 bar 上的数据。也就是说,用户模型的核心逻辑都是写在该函数中的,如获取数据,设置下单条件等。在 handlebar 中处理完数据后,用户可以通过 paint 方法将需要绘图输出的结果返回给界面。界面会将输出结果如实的展示出来。
(4)ContextInfo
ContextInfo 是整个 Python 框架中的一个核心对象。它包含了各种与 Python 底层框架交互的 API 方法,也是一个全局的上下文环境,可以在 init 以及 handlebar 这两个函数中自由地传递用户创建的各种自定义数据。
文绉绉的,实际写一个策略,必须包含下面两个函数,而且参数也要一致,参数名随意,不过用默认的就好了。你随便改成没有意义的字符,后面自己看代码也是很麻烦。
def init(ContextInfo):
pass
def handlebar(ContextInfo):
pass
init 和 handlebar 是 Python 模型中最重要的方法,也是唯二由 C++ 直接调用的方法,所有的执行代码都尽量写在这两个方法中或由其中的函数调用。【个人不太喜欢这样】
回测时间设置,在右边的菜单栏,有个回测参数,里面设置时间;在菜单“基本信息”里面 ,可以设置回测的时间间隔,可以使用分钟线,日线,小时等等不同周期,不过无法做到tick的回测。最小的只能到分钟。
但是如果你有秒的tick数据,自己写个回测框架也是可以做到秒级的tick级别的回测。很早前笔者就在星球上提供了完整的源码和数据,初学者也可以拿着去改,只要后续更新tick数据,就可以不断的回测策略的最新状态。
你写的回测实盘python代码,是保存在本地的文件夹的:
C:\iquant_gx\python, 前面的C:\iquant_gx 是你的iquant安装路径。
而且底下也有很多的现成的代码:
部分代码可以直接用pycharm就可以打开,没有加密的,但也有一些是加密了的。
比如这个自动逆回购是现成的:
对,这里就有,很多人还到处找人写;
# encoding:gbk
import logging
from datetime import datetime, timedelta
from decimal import Decimal as D
from decimal import InvalidOperation
logging.basicConfig(level=logging.INFO)
# 挂单失败后的等待时长,以秒计
TIMEOUT_ON_FAIL_SEC = 30
# 等待account_callback的时长
# RUN_TIME_DELAY = 30
# how is this not defined in package??
MORNING_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '093000', '%Y%m%d%H%M%S')
MORNING_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '113000', '%Y%m%d%H%M%S')
NOON_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '130000', '%Y%m%d%H%M%S')
NOON_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '153000', '%Y%m%d%H%M%S')
# for SH only
TRANS_COST_1D = D('5e-6')
TRANS_COST_LONG = D('1.5e-7')
TRANS_COST_MAX = 100
# ORDER LIMITS
SH_UPPER = 1e7
SH_LOWER = 1e5
SZ_UPPER = 1e8
SZ_LOWER = 1e3
# ASSET NAME DICT
SH_REV_REPO = {'上交所1天': '204001.SH', '上交所2天': '204002.SH', '上交所3天': '204003.SH',
'上交所4天': '204004.SH', '上交所7天': '204007.SH', '上交所14天': '204014.SH',
'上交所28天': '204028.SH', '上交所91天': '204091.SH', '上交所182天': '204182.SH',
}
SZ_REV_REPO = {'深交所3天': '131800.SZ', '深交所7天': '131801.SZ', '深交所14天': '131802.SZ',
'深交所28天': '131803.SZ', '深交所91天': '131805.SZ', '深交所182天': '131806.SZ',
'深交所4天': '131809.SZ', '深交所1天': '131810.SZ', '深交所2天': '131811.SZ',
}
def init(ContextInfo):
ContextInfo.accID = account
ContextInfo.set_account(ContextInfo.accID)
ContextInfo.use_all_cap = False if ALL_CAP == '否' else True
# global trading control, set to False if detected error on user's side
# stop() does not halt strat
ContextInfo.order_control = False
if not ContextInfo.use_all_cap:
try:
ContextInfo.dollar_vol = float(D(DOLLAR_VOL))
except InvalidOperation:
ContextInfo.order_control = True
raise ValueError('读取资金量失败')
else:
if DOLLAR_VOL != '':
logging.warning('已设定使用全部账户资金,忽略所设置资金量')
try:
ContextInfo.start_time = datetime.strptime(datetime.now().strftime('%Y%m%d') + str(START_TIME), '%Y%m%d%H%M%S')
ContextInfo.asset_name = SH_REV_REPO[ASSET_NAME]
except KeyError:
ContextInfo.asset_name = SZ_REV_REPO[ASSET_NAME]
except ValueError as error:
if 'unconverted data remains' in str(error):
ContextInfo.order_control = True
raise ValueError('读取挂单时间失败')
if not (MORNING_END > ContextInfo.start_time >= MORNING_START) \
and not (NOON_END > ContextInfo.start_time >= NOON_START):
ContextInfo.order_control = True
raise ValueError('挂单时间不在可交易时间内')
ContextInfo.can_order = False
ContextInfo.order_done = False
if not ContextInfo.order_control:
ContextInfo.run_time("place_order", "{0}nSecond".format(TIMEOUT_ON_FAIL_SEC),
ContextInfo.start_time.strftime('%Y-%m-%d %H:%M:%S'), 'SH')
def account_callback(ContextInfo, accountInfo):
if not ContextInfo.can_order:
ContextInfo.can_order = True
if ContextInfo.use_all_cap:
ContextInfo.dollar_vol = accountInfo.m_dAvailable
else:
if ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('下单额度大于账户可用资金')
# check if order satisfies lower limit for each exchange
if ('SH' in ContextInfo.asset_name and ContextInfo.dollar_vol < SH_LOWER) \
or ('SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol < SZ_LOWER):
ContextInfo.order_control = True
raise ValueError('下单额度低于交易所最低限额')
# checks dollar_vol and rounds the total amount
if 'SH' in ContextInfo.asset_name and ContextInfo.dollar_vol % SH_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SH_LOWER) * SH_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
elif 'SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol % SZ_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SZ_LOWER) * SZ_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
'''
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.dollar_vol // SH_UPPER)
remain_order = ContextInfo.dollar_vol - num_batch_order * SH_UPPER
if ContextInfo.asset_name == '204001.SH':
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_1D
else:
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_LONG
if transaction_cost + ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('可用资金不足以垫付交易金额与手续费')
'''
ContextInfo.remain_vol = ContextInfo.dollar_vol
def handlebar(ContextInfo):
return
def place_order(ContextInfo):
if not ContextInfo.can_order or ContextInfo.order_control:
return
if not ContextInfo.order_done:
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.remain_vol // SH_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SH_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SH_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SH_UPPER, order_remark, 1,
order_remark, ContextInfo)
else:
num_batch_order = int(ContextInfo.remain_vol // SZ_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SZ_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SZ_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SZ_UPPER, order_remark, 1,
order_remark, ContextInfo)
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(remain_order, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, remain_order, order_remark, 1,
order_remark, ContextInfo)
ContextInfo.remain_vol = 0
ContextInfo.order_done = True
def order_callback(ContextInfo, orderInfo):
curr_remark = orderInfo.m_strRemark
curr_status = orderInfo.m_nOrderStatus
if '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 57:
ContextInfo.order_done = False
# up the leftover dollar vol by failed amount
# logging.info('reported trade amount:{0}, reported_trade_volume:{1}'.format(orderInfo.m_dTradeAmount, orderInfo.m_nVolumeTotal))
# 单张100元
ContextInfo.remain_vol += orderInfo.m_nVolumeTotal * 100
if '交易时间不合法' in orderInfo.m_strCancelInfo:
ContextInfo.order_control = True
raise ValueError('国债逆回购:未能在交易时间内完成下单,停止报单。余量{0}元未报'.format(ContextInfo.remain_vol))
logging.warning('国债逆回购:报单废单,原因:\"{0}\",尝试重报'.format(orderInfo.m_strCancelInfo))
elif '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 50:
logging.info('国债逆回购:报单{0}元成功'.format(orderInfo.m_nVolumeTotal * 100))
return
待续,不定期更新
公众号:

星球:

ptrade获取分时成交数据-LEVEL2数据逐笔数据
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 6983 次浏览 • 2023-02-04 12:27
中提供了获取分时成交的数据。
使用场景
该函数在交易模块可用
接口说明
该接口用于获取当日分时成交行情数据。
注意事项:
1、沪深市场都有分时成交数据;
2、分时成交数据需开通level2行情才有数据推送,否则无数据返回;
返回字段:
返回
返回一个OrderedDict对象,包含每只代码的分时成交行情数据。(OrderedDict([(),()...]))
返回结果字段介绍:
time_stamp: 时间戳毫秒级(str:numpy.int64);
hq_px: 价格(str:numpy.float64);
hq_px64: 价格(str:numpy.int64)(行情暂不支持,返回均为0);
business_amount: 成交数量(str:numpy.int64);
business_balance: 成交金额(str:numpy.int64);
business_count: 成交笔数(str:numpy.int64);
business_direction: 成交方向(0:卖,1:买,2:平盘)(str:numpy.int64);
amount: 持仓量(str:numpy.int64)(行情暂不支持,返回均为0);
start_index: 分笔关联的逐笔开始序号(str:numpy.int64)(行情暂不支持,返回均为0);
end_index: 分笔关联的逐笔结束序号(str:numpy.int64)(行情暂不支持,返回均为0);
示例代码:
def initialize(context):
g.security = '000001.SZ'
set_universe(g.security)
def handle_data(context, data):
#获取000001.SZ的分时成交数据
direction_data = get_tick_direction(g.security)
log.info(direction_data)
#获取指定股票列表分时成交数据
direction_data = get_tick_direction(['000002.SZ','000032.SZ'])
log.info(direction_data)
#获取成交量
business_amount = direction_data['000002.SZ']['business_amount']
log.info('分时成交的成交量为:%s' % business_amount)
不过在handle_bar中或者tick_data中,实际行情推送最快也要3s,所以拿到的level2的是切片数据,即使拿到很多数据,可是行情获取时间间隔还是3s, 无法做到和qmt那样的level2逐笔订阅驱动。还有level2数据需要收费。ptrade目前常用的几个券商都不支持level2的。
目前有万一免五的qmt ptrade量化交易接口的券商吗?
查看全部
中提供了获取分时成交的数据。
使用场景
该函数在交易模块可用
接口说明
该接口用于获取当日分时成交行情数据。
注意事项:
1、沪深市场都有分时成交数据;
2、分时成交数据需开通level2行情才有数据推送,否则无数据返回;
返回字段:
返回
返回一个OrderedDict对象,包含每只代码的分时成交行情数据。(OrderedDict([(),()...]))
返回结果字段介绍:
time_stamp: 时间戳毫秒级(str:numpy.int64);
hq_px: 价格(str:numpy.float64);
hq_px64: 价格(str:numpy.int64)(行情暂不支持,返回均为0);
business_amount: 成交数量(str:numpy.int64);
business_balance: 成交金额(str:numpy.int64);
business_count: 成交笔数(str:numpy.int64);
business_direction: 成交方向(0:卖,1:买,2:平盘)(str:numpy.int64);
amount: 持仓量(str:numpy.int64)(行情暂不支持,返回均为0);
start_index: 分笔关联的逐笔开始序号(str:numpy.int64)(行情暂不支持,返回均为0);
end_index: 分笔关联的逐笔结束序号(str:numpy.int64)(行情暂不支持,返回均为0);
示例代码:
def initialize(context):
g.security = '000001.SZ'
set_universe(g.security)
def handle_data(context, data):
#获取000001.SZ的分时成交数据
direction_data = get_tick_direction(g.security)
log.info(direction_data)
#获取指定股票列表分时成交数据
direction_data = get_tick_direction(['000002.SZ','000032.SZ'])
log.info(direction_data)
#获取成交量
business_amount = direction_data['000002.SZ']['business_amount']
log.info('分时成交的成交量为:%s' % business_amount)
不过在handle_bar中或者tick_data中,实际行情推送最快也要3s,所以拿到的level2的是切片数据,即使拿到很多数据,可是行情获取时间间隔还是3s, 无法做到和qmt那样的level2逐笔订阅驱动。还有level2数据需要收费。ptrade目前常用的几个券商都不支持level2的。
目前有万一免五的qmt ptrade量化交易接口的券商吗?

国信可以使用miniqmt吗?
QMT • 李魔佛 发表了文章 • 0 个评论 • 8917 次浏览 • 2023-01-21 15:52
所以笔者特意去问了下国信的好友兼营业部经理,但他回复说,个人只要申请,就可以开通mini qmt。如果不申请,是无法使用的,无法连接上去。
但因为开通这个是不用门槛的,可能会有部分不懂的或者不愿意的经理会和客户说不支持,或者需要机构这样话语。
具体情况,具体分析。
1. 国信证券iQuant策略交易平台精简版是指国信证券iQuant策略交易平台更专业快速且简洁的版本,满足股票、期货、期权、基金等全品种交易需求。
2. 风险等级:R4
投资期限:0-1年
投资品种:权益类投资品种如股票、混合型基金、偏股型基金、股票型基金等。
3. 平台使用不收取费用。
具体的申请表如下:
不过申请了这个权限后,只能进行拉取数据,并没有交易权限。。交易权限需要机构才能开通。郁闷,看来国信的miniqmt是无法进行交易的了,只能白嫖点数据。
如果需要文字word版本,
可以到公众号后台回复: 国信mini申请
获取word版本。
或者加微信开通指定的营业部的国信qmt(iquant), 也可以帮你开通mini qmt。
查看全部
之前群里有国信的小伙伴说,国信的mini qmt无法使用的。
所以笔者特意去问了下国信的好友兼营业部经理,但他回复说,个人只要申请,就可以开通mini qmt。如果不申请,是无法使用的,无法连接上去。
但因为开通这个是不用门槛的,可能会有部分不懂的或者不愿意的经理会和客户说不支持,或者需要机构这样话语。
具体情况,具体分析。
1. 国信证券iQuant策略交易平台精简版是指国信证券iQuant策略交易平台更专业快速且简洁的版本,满足股票、期货、期权、基金等全品种交易需求。
2. 风险等级:R4
投资期限:0-1年
投资品种:权益类投资品种如股票、混合型基金、偏股型基金、股票型基金等。
3. 平台使用不收取费用。
具体的申请表如下:
不过申请了这个权限后,只能进行拉取数据,并没有交易权限。。交易权限需要机构才能开通。郁闷,看来国信的miniqmt是无法进行交易的了,只能白嫖点数据。
如果需要文字word版本,
可以到公众号后台回复: 国信mini申请
获取word版本。

或者加微信开通指定的营业部的国信qmt(iquant), 也可以帮你开通mini qmt。

Ptrade获取可转债强赎数据
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 3814 次浏览 • 2022-12-21 15:50
所以在可转债的策略里面,把强赎的转债排除掉,是一个不错的因子。
但内置的ptrade接口数据并无提供任何转债相关的数据。
不过笔者这里提供了一个自研的数据接口。
http://ptradeapi.com/#%E5%8F%AF%E8%BD%AC%E5%80%BA%E5%BC%BA%E8%B5%8E%E4%B8%8E%E6%95%B0%E6%97%A5%E5%AD%90
方便在ptrade里面调用。
查看全部
所以在可转债的策略里面,把强赎的转债排除掉,是一个不错的因子。
但内置的ptrade接口数据并无提供任何转债相关的数据。
不过笔者这里提供了一个自研的数据接口。
http://ptradeapi.com/#%E5%8F%AF%E8%BD%AC%E5%80%BA%E5%BC%BA%E8%B5%8E%E4%B8%8E%E6%95%B0%E6%97%A5%E5%AD%90
方便在ptrade里面调用。
Ptrade QMT 哪家费率最便宜,门槛最低?
券商万一免五 • 绫波丽 发表了文章 • 0 个评论 • 6794 次浏览 • 2022-11-27 19:09
笔者只会推荐合适的券商和量化接口给你,而不会推荐坑爹的券商给你。
如果你不信任,绕路即可,莫浪费大家时间。或者你有好的资源或者券商,你也可以推荐给我,可以给你发红包,奖励你提供有用的情报信息。
目前支持ptrade,qmt可以股票可以免五(0.1元起步)的券商,只有国盛,需要的可以找我开。 但是有入金门槛,ptrade门槛30w, qmt 的门槛50w。 国盛的ptrade可以链接外网。其他家的不行。但国盛的qmt不支持运行在云服务器。
其他家的qmt是支持的云服务器的,但国金的qmt会每天自动退出,需要每次手动点击登录,我也写了一个自动登录的小脚本,开完户的朋友可以拿去用用。
门槛低的国信,适合新手使用,但是没有miniqmt,这个东西也不一定适合你。 真的需要这个功能,在qmt里面可以写一段代码,让它把下单接口变成http指令,把下单功能独立出来,也是可以的。不过这个属于进阶功能。 需要的也可以把代码给你。
笔者用过大部分券商的ptrade qmt,所以个人的指导与推荐还是很有指导意见的。 写过的策略也大部分人(99%)多, 平台好坏,坑的多寡,哪里有雷,都已经摸清摸楚。 可以大大节省你们的时间。 当然你也可以忽略,自己去折腾折腾。选ptrade 还是qmt,然后哪个券商,什么费率。
需要开通ptrade - qmt 低门槛 低费率 的 或者可以提供更低费用的资源的可以加微信:
ptrade 接口文档: http://ptradeapi.com
查看全部
笔者只会推荐合适的券商和量化接口给你,而不会推荐坑爹的券商给你。
如果你不信任,绕路即可,莫浪费大家时间。或者你有好的资源或者券商,你也可以推荐给我,可以给你发红包,奖励你提供有用的情报信息。
目前支持ptrade,qmt可以股票可以免五(0.1元起步)的券商,只有国盛,需要的可以找我开。 但是有入金门槛,ptrade门槛30w, qmt 的门槛50w。 国盛的ptrade可以链接外网。其他家的不行。但国盛的qmt不支持运行在云服务器。
其他家的qmt是支持的云服务器的,但国金的qmt会每天自动退出,需要每次手动点击登录,我也写了一个自动登录的小脚本,开完户的朋友可以拿去用用。
门槛低的国信,适合新手使用,但是没有miniqmt,这个东西也不一定适合你。 真的需要这个功能,在qmt里面可以写一段代码,让它把下单接口变成http指令,把下单功能独立出来,也是可以的。不过这个属于进阶功能。 需要的也可以把代码给你。
笔者用过大部分券商的ptrade qmt,所以个人的指导与推荐还是很有指导意见的。 写过的策略也大部分人(99%)多, 平台好坏,坑的多寡,哪里有雷,都已经摸清摸楚。 可以大大节省你们的时间。 当然你也可以忽略,自己去折腾折腾。选ptrade 还是qmt,然后哪个券商,什么费率。
需要开通ptrade - qmt 低门槛 低费率 的 或者可以提供更低费用的资源的可以加微信:

ptrade 接口文档: http://ptradeapi.com
不同券商的ptrade的异同
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 4771 次浏览 • 2022-06-17 16:36
1. 湘财无法访问外网,国盛的可以
2.
get_cb_list 获取可转债列表 的 国盛没有
get_history 获取历史数据函数
get_history(5, frequency='1d', field='close', security_list=['123084.SZ'], fq=None, include=False, fill='nan')国盛是没有fill参数的。
持续更新。。。待续
Ptrade开户联系:
查看全部
ptrade qmt量化平台收费吗?
券商万一免五 • 李魔佛 回复了问题 • 2 人关注 • 1 个回复 • 7868 次浏览 • 2022-07-13 17:04
开通Ptrade Python量化接口 国金证券/国盛证券
股票 • 绫波丽 发表了文章 • 0 个评论 • 31908 次浏览 • 2021-07-06 08:40
而退而求其次使用按键精灵,模拟点击交易软件进行点击下单,非常不稳定,无法判断下单后是否成交,也无法实时获取行情数据。如果使用tushare或者新浪接口数据,扫描一次全市场的行情用时很久且不稳定,等扫描结束,再下单,此时价格可能已经是几分钟前的了,且此类接口调用次数多是会被封IP的。
笔者使用的是券商提供的量化软件:Ptrade。是恒生电子研发的提供给机构使用的程序化交易软件。提供策略回测,下单API接口,实时行情获取,并且使用的开发语言python,易于上手。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
集合竞价追涨停策略def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
双均线策略def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
pass
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
security = g.security
#得到十日历史价格
df = get_history(10, '1d', 'close', security, fq=None, include=False)
# 得到五日均线价格
ma5 = round(df['close'][-5:].mean(), 3)
# 得到十日均线价格
ma10 = round(df['close'][-10:].mean(), 3)
# 取得昨天收盘价
price = data[security]['close']
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(security, cash)
# 记录这次买入
log.info("Buying %s" % (security))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(security).amount > 0:
# 全部卖出
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
tick级别均线策略
通俗点就是按照秒级别进行操作。def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每3秒运行一次主函数
run_interval(context, func, seconds=3)
#盘前准备历史数据
def before_trading_start(context, data):
history = get_history(10, '1d', 'close', g.security, fq='pre', include=False)
g.close_array = history['close'].values
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def func(context):
stock = g.security
#获取最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
# 得到五日均线价格
days = 5
ma5 = get_MA_day(stock, days, g.close_array[-4:], price)
# 得到十日均线价格
days = 10
ma10 = get_MA_day(stock, days, g.close_array[-9:], price)
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(stock, cash)
# 记录这次买入
log.info("Buying %s" % (stock))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(stock).amount > 0:
# 全部卖出
order_target(stock, 0)
# 记录这次卖出
log.info("Selling %s" % (stock))
#计算实时均线函数
def get_MA_day(stock,days,close_array,current_price):
close_sum = close_array[-(days-1):].sum()
MA = (current_price + close_sum)/days
return MA
def handle_data(context, data):
pass
macd策略def f_expma(N,m,EXPMA1,price):
a = m/(N+1)
EXPMA2 = a * price + (1 - a)*EXPMA1
return EXPMA2 #2为后一天值
#定义macd函数,输入平滑系数参数、前一日值,输出当日值
def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
DIF2 = EXPMA12_2 - EXPMA26_2
a = m/(N3+1)
DEA2 = a * DIF2 + (1 - a)*DEA1
BAR2=2*(DIF2-DEA2)
return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
def initialize(context):
global init_price
init_price = None
# 获取沪深300股票
g.security = get_index_stocks('000300.SS')
#g.security = ['600570.SS']
# 设置我们要操作的股票池, 这里我们只操作一支股票
set_universe(g.security)
def handle_data(context, data):
# 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
# 从股票上市至今的所有历史数据,即增加获取的天数
close_price = get_history(2, '1d', field='close', security_list=g.security)
#如果是停牌不进行计算
for security in g.security:
if data[security].is_open >0:
global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
if init_price is None:
init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
EXPMA12_1 = init_price
EXPMA26_1 = init_price
DIF1 = init_price
DEA1 = init_price
# m用于计算平滑系数a=m/(N+1)
m = 2.0
#设定指数平滑基期数
N1 = 12
N2 = 26
N3 = 9
EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
# 取得当前价格
current_price = data[security].price
# 取得当前的现金
cash = context.portfolio.cash
# DIF、DEA均为正,DIF向上突破DEA,买入信号参考
if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
# 计算可以买多少只股票
number_of_shares = int(cash/current_price)
# 购买量大于0时,下单
if number_of_shares > 0:
# 以市单价买入股票,日回测时即是开盘价
order(security, +number_of_shares)
# 记录这次买入
log.info("Buying %s" % (security))
# DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
# 卖出所有股票,使这只股票的最终持有量为0
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
# 将今日的值赋给全局变量作为下一次前一日的值
DEA1 = DEA2
DIF1 = DIF2
EXPMA12_1 = EXPMA12_2
EXPMA26_1 = EXPMA26_2
软件与交易接口开通条件:
开通该券商后,存入资金指定资金即可开通。开通后股票交易费率万一
本身券商的交易费率为股票万一,可转债沪百万分之五,深十万分之五,基金万0.5,非常厚道。
不太了解量化行业的可以了解下,不少面向机构的量化交易软件的佣金是万2.5的,且开户门槛高,基本是500W以上,比如华泰的matic量化的门槛是1千万元起步。
所以笔者还是很推荐目前该券商的量化交易接口。
需要开通咨询了解的朋友可以扫码联系:
开通券商账户后可以 可以先试用,再考虑是否开通量化接口权限 查看全部
而退而求其次使用按键精灵,模拟点击交易软件进行点击下单,非常不稳定,无法判断下单后是否成交,也无法实时获取行情数据。如果使用tushare或者新浪接口数据,扫描一次全市场的行情用时很久且不稳定,等扫描结束,再下单,此时价格可能已经是几分钟前的了,且此类接口调用次数多是会被封IP的。
笔者使用的是券商提供的量化软件:Ptrade。是恒生电子研发的提供给机构使用的程序化交易软件。提供策略回测,下单API接口,实时行情获取,并且使用的开发语言python,易于上手。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
集合竞价追涨停策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
双均线策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
pass
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
security = g.security
#得到十日历史价格
df = get_history(10, '1d', 'close', security, fq=None, include=False)
# 得到五日均线价格
ma5 = round(df['close'][-5:].mean(), 3)
# 得到十日均线价格
ma10 = round(df['close'][-10:].mean(), 3)
# 取得昨天收盘价
price = data[security]['close']
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(security, cash)
# 记录这次买入
log.info("Buying %s" % (security))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(security).amount > 0:
# 全部卖出
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
tick级别均线策略
通俗点就是按照秒级别进行操作。
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每3秒运行一次主函数
run_interval(context, func, seconds=3)
#盘前准备历史数据
def before_trading_start(context, data):
history = get_history(10, '1d', 'close', g.security, fq='pre', include=False)
g.close_array = history['close'].values
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def func(context):
stock = g.security
#获取最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
# 得到五日均线价格
days = 5
ma5 = get_MA_day(stock, days, g.close_array[-4:], price)
# 得到十日均线价格
days = 10
ma10 = get_MA_day(stock, days, g.close_array[-9:], price)
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(stock, cash)
# 记录这次买入
log.info("Buying %s" % (stock))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(stock).amount > 0:
# 全部卖出
order_target(stock, 0)
# 记录这次卖出
log.info("Selling %s" % (stock))
#计算实时均线函数
def get_MA_day(stock,days,close_array,current_price):
close_sum = close_array[-(days-1):].sum()
MA = (current_price + close_sum)/days
return MA
def handle_data(context, data):
pass
macd策略
def f_expma(N,m,EXPMA1,price):
a = m/(N+1)
EXPMA2 = a * price + (1 - a)*EXPMA1
return EXPMA2 #2为后一天值
#定义macd函数,输入平滑系数参数、前一日值,输出当日值
def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
DIF2 = EXPMA12_2 - EXPMA26_2
a = m/(N3+1)
DEA2 = a * DIF2 + (1 - a)*DEA1
BAR2=2*(DIF2-DEA2)
return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
def initialize(context):
global init_price
init_price = None
# 获取沪深300股票
g.security = get_index_stocks('000300.SS')
#g.security = ['600570.SS']
# 设置我们要操作的股票池, 这里我们只操作一支股票
set_universe(g.security)
def handle_data(context, data):
# 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
# 从股票上市至今的所有历史数据,即增加获取的天数
close_price = get_history(2, '1d', field='close', security_list=g.security)
#如果是停牌不进行计算
for security in g.security:
if data[security].is_open >0:
global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
if init_price is None:
init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
EXPMA12_1 = init_price
EXPMA26_1 = init_price
DIF1 = init_price
DEA1 = init_price
# m用于计算平滑系数a=m/(N+1)
m = 2.0
#设定指数平滑基期数
N1 = 12
N2 = 26
N3 = 9
EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
# 取得当前价格
current_price = data[security].price
# 取得当前的现金
cash = context.portfolio.cash
# DIF、DEA均为正,DIF向上突破DEA,买入信号参考
if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
# 计算可以买多少只股票
number_of_shares = int(cash/current_price)
# 购买量大于0时,下单
if number_of_shares > 0:
# 以市单价买入股票,日回测时即是开盘价
order(security, +number_of_shares)
# 记录这次买入
log.info("Buying %s" % (security))
# DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
# 卖出所有股票,使这只股票的最终持有量为0
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
# 将今日的值赋给全局变量作为下一次前一日的值
DEA1 = DEA2
DIF1 = DIF2
EXPMA12_1 = EXPMA12_2
EXPMA26_1 = EXPMA26_2
软件与交易接口开通条件:
开通该券商后,存入资金指定资金即可开通。开通后股票交易费率万一
本身券商的交易费率为股票万一,可转债沪百万分之五,深十万分之五,基金万0.5,非常厚道。
不太了解量化行业的可以了解下,不少面向机构的量化交易软件的佣金是万2.5的,且开户门槛高,基本是500W以上,比如华泰的matic量化的门槛是1千万元起步。
所以笔者还是很推荐目前该券商的量化交易接口。
需要开通咨询了解的朋友可以扫码联系:

开通券商账户后可以 可以先试用,再考虑是否开通量化接口权限
量化交易接口python A股
股票 • 绫波丽 发表了文章 • 0 个评论 • 14236 次浏览 • 2021-07-01 11:22
实际操作也好,几乎没见几个人教你怎么用程序下单,实盘交易。
稍微好点的easytrader使用的是模拟点击交易软件进行点击下单,基本无法判断下单后是否成交,也无法实时获取行情数据。别跟我说用tushare或者新浪这些接口数据,除非你做的是低频交易。
试试扫描一次全市场的行情看看用时多少?等得到满足条件了,再下单,此时价格可能已经在涨停板上封住了。
笔者使用的是券商提供的量化软件:Ptrade。
是恒生电子研发的提供给券商机构使用的程序化交易软件。提供策略回测,自动下单功能,使用的开发语言python。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。
如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。
实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
双均线策略 def initialize(context):
2 # 初始化此策略
3 # 设置我们要操作的股票池, 这里我们只操作一支股票
4 g.security = '600570.SS'
5 set_universe(g.security)
6 pass
7
8 #当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
9 def handle_data(context, data):
10 security = g.security
11
12 #得到十日历史价格
13 df = get_history(10, '1d', 'close', security, fq=None, include=False)
14
15 # 得到五日均线价格
16 ma5 = round(df['close'][-5:].mean(), 3)
17
18 # 得到十日均线价格
19 ma10 = round(df['close'][-10:].mean(), 3)
20
21 # 取得昨天收盘价
22 price = data[security]['close']
23
24 # 得到当前资金余额
25 cash = context.portfolio.cash
26
27 # 如果当前有余额,并且五日均线大于十日均线
28 if ma5 > ma10:
29 # 用所有 cash 买入股票
30 order_value(security, cash)
31 # 记录这次买入
32 log.info("Buying %s" % (security))
33
34 # 如果五日均线小于十日均线,并且目前有头寸
35 elif ma5 < ma10 and get_position(security).amount > 0:
36 # 全部卖出
37 order_target(security, 0)
38 # 记录这次卖出
39 log.info("Selling %s" % (security))
macd策略
指数平滑均线函数,以price计算,可以选择收盘、开盘价等价格,N为时间周期,m用于计算平滑系数a=m/(N+1),EXPMA1为前一日值 def f_expma(N,m,EXPMA1,price):
2 a = m/(N+1)
3 EXPMA2 = a * price + (1 - a)*EXPMA1
4 return EXPMA2 #2为后一天值
5
6 #定义macd函数,输入平滑系数参数、前一日值,输出当日值
7 def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
8 EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
9 EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
10 DIF2 = EXPMA12_2 - EXPMA26_2
11 a = m/(N3+1)
12 DEA2 = a * DIF2 + (1 - a)*DEA1
13 BAR2=2*(DIF2-DEA2)
14 return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
15
16 def initialize(context):
17 global init_price
18 init_price = None
19 # 获取沪深300股票
20 g.security = get_index_stocks('000300.SS')
21 #g.security = ['600570.SS']
22 # 设置我们要操作的股票池, 这里我们只操作一支股票
23 set_universe(g.security)
24
25 def handle_data(context, data):
26 # 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
27 # 从股票上市至今的所有历史数据,即增加获取的天数
28 close_price = get_history(2, '1d', field='close', security_list=g.security)
29 #如果是停牌不进行计算
30 for security in g.security:
31 if data[security].is_open >0:
32 global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
33 if init_price is None:
34 init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
35 EXPMA12_1 = init_price
36 EXPMA26_1 = init_price
37 DIF1 = init_price
38 DEA1 = init_price
39 # m用于计算平滑系数a=m/(N+1)
40 m = 2.0
41 #设定指数平滑基期数
42 N1 = 12
43 N2 = 26
44 N3 = 9
45 EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
46 # 取得当前价格
47 current_price = data[security].price
48 # 取得当前的现金
49 cash = context.portfolio.cash
50 # DIF、DEA均为正,DIF向上突破DEA,买入信号参考
51 if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
52 # 计算可以买多少只股票
53 number_of_shares = int(cash/current_price)
54 # 购买量大于0时,下单
55 if number_of_shares > 0:
56 # 以市单价买入股票,日回测时即是开盘价
57 order(security, +number_of_shares)
58 # 记录这次买入
59 log.info("Buying %s" % (security))
60 # DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
61 elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
62 # 卖出所有股票,使这只股票的最终持有量为0
63 order_target(security, 0)
64 # 记录这次卖出
65 log.info("Selling %s" % (security))
66 # 将今日的值赋给全局变量作为下一次前一日的值
67 DEA1 = DEA2
68 DIF1 = DIF2
69 EXPMA12_1 = EXPMA12_2
70 EXPMA26_1 = EXPMA26_2
同时也支持可转债T+0交易,笔者平时也主要是进行的可转债的交易。
软件与交易接口开通条件,
开通改券商后,存入资金50W放2周即可开通,开通后可取出。
本身券商的交易费率为股票万一免五,可转债百万分之二,非常厚道,因为不少面向机构的量化交易软件的佣金是万2.5的,笔者之前在国金渠道开的就是,坑的一比。所以笔者还是很推荐目前该券商的量化交易接口。
需要可以关注公众号获取开通链接: 查看全部
实际操作也好,几乎没见几个人教你怎么用程序下单,实盘交易。
稍微好点的easytrader使用的是模拟点击交易软件进行点击下单,基本无法判断下单后是否成交,也无法实时获取行情数据。别跟我说用tushare或者新浪这些接口数据,除非你做的是低频交易。
试试扫描一次全市场的行情看看用时多少?等得到满足条件了,再下单,此时价格可能已经在涨停板上封住了。
笔者使用的是券商提供的量化软件:Ptrade。
是恒生电子研发的提供给券商机构使用的程序化交易软件。提供策略回测,自动下单功能,使用的开发语言python。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。
如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。
实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
双均线策略
def initialize(context):
2 # 初始化此策略
3 # 设置我们要操作的股票池, 这里我们只操作一支股票
4 g.security = '600570.SS'
5 set_universe(g.security)
6 pass
7
8 #当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
9 def handle_data(context, data):
10 security = g.security
11
12 #得到十日历史价格
13 df = get_history(10, '1d', 'close', security, fq=None, include=False)
14
15 # 得到五日均线价格
16 ma5 = round(df['close'][-5:].mean(), 3)
17
18 # 得到十日均线价格
19 ma10 = round(df['close'][-10:].mean(), 3)
20
21 # 取得昨天收盘价
22 price = data[security]['close']
23
24 # 得到当前资金余额
25 cash = context.portfolio.cash
26
27 # 如果当前有余额,并且五日均线大于十日均线
28 if ma5 > ma10:
29 # 用所有 cash 买入股票
30 order_value(security, cash)
31 # 记录这次买入
32 log.info("Buying %s" % (security))
33
34 # 如果五日均线小于十日均线,并且目前有头寸
35 elif ma5 < ma10 and get_position(security).amount > 0:
36 # 全部卖出
37 order_target(security, 0)
38 # 记录这次卖出
39 log.info("Selling %s" % (security))
macd策略
指数平滑均线函数,以price计算,可以选择收盘、开盘价等价格,N为时间周期,m用于计算平滑系数a=m/(N+1),EXPMA1为前一日值
def f_expma(N,m,EXPMA1,price):
2 a = m/(N+1)
3 EXPMA2 = a * price + (1 - a)*EXPMA1
4 return EXPMA2 #2为后一天值
5
6 #定义macd函数,输入平滑系数参数、前一日值,输出当日值
7 def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
8 EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
9 EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
10 DIF2 = EXPMA12_2 - EXPMA26_2
11 a = m/(N3+1)
12 DEA2 = a * DIF2 + (1 - a)*DEA1
13 BAR2=2*(DIF2-DEA2)
14 return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
15
16 def initialize(context):
17 global init_price
18 init_price = None
19 # 获取沪深300股票
20 g.security = get_index_stocks('000300.SS')
21 #g.security = ['600570.SS']
22 # 设置我们要操作的股票池, 这里我们只操作一支股票
23 set_universe(g.security)
24
25 def handle_data(context, data):
26 # 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
27 # 从股票上市至今的所有历史数据,即增加获取的天数
28 close_price = get_history(2, '1d', field='close', security_list=g.security)
29 #如果是停牌不进行计算
30 for security in g.security:
31 if data[security].is_open >0:
32 global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
33 if init_price is None:
34 init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
35 EXPMA12_1 = init_price
36 EXPMA26_1 = init_price
37 DIF1 = init_price
38 DEA1 = init_price
39 # m用于计算平滑系数a=m/(N+1)
40 m = 2.0
41 #设定指数平滑基期数
42 N1 = 12
43 N2 = 26
44 N3 = 9
45 EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
46 # 取得当前价格
47 current_price = data[security].price
48 # 取得当前的现金
49 cash = context.portfolio.cash
50 # DIF、DEA均为正,DIF向上突破DEA,买入信号参考
51 if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
52 # 计算可以买多少只股票
53 number_of_shares = int(cash/current_price)
54 # 购买量大于0时,下单
55 if number_of_shares > 0:
56 # 以市单价买入股票,日回测时即是开盘价
57 order(security, +number_of_shares)
58 # 记录这次买入
59 log.info("Buying %s" % (security))
60 # DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
61 elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
62 # 卖出所有股票,使这只股票的最终持有量为0
63 order_target(security, 0)
64 # 记录这次卖出
65 log.info("Selling %s" % (security))
66 # 将今日的值赋给全局变量作为下一次前一日的值
67 DEA1 = DEA2
68 DIF1 = DIF2
69 EXPMA12_1 = EXPMA12_2
70 EXPMA26_1 = EXPMA26_2
同时也支持可转债T+0交易,笔者平时也主要是进行的可转债的交易。
软件与交易接口开通条件,
开通改券商后,存入资金50W放2周即可开通,开通后可取出。
本身券商的交易费率为股票万一免五,可转债百万分之二,非常厚道,因为不少面向机构的量化交易软件的佣金是万2.5的,笔者之前在国金渠道开的就是,坑的一比。所以笔者还是很推荐目前该券商的量化交易接口。
需要可以关注公众号获取开通链接:
python判断可转债是否强赎
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 4247 次浏览 • 2021-04-02 13:41
更新:
制作好了一个接口,用户可以直接调用。
数据来源与集思录。
获取 排除满足强赎天数剩余N天的可转债,排除强赎可转债。
比如:DAY=4 ,那么假设强赎满足天数为15天,那么返回市场上强赎强赎倒数天数大于4天的可转债,即返回小于或者等于11天以下的转债。把满足条件还差4天的转债排除掉了,当然,已经公告强赎的也会被排除。
import requests
URL = 'http://11.11.11.11/api/redeem/'
# DAY 强赎倒数剩余天数小于 DAY (4)天, 已经公告强赎的也是被排除的
DAY = 4
SIGN = '私信星主获取' # sign和以前一致
data = {'day': DAY,
'sign': SIGN}
r = requests.post(URL, data=data)
print(r.json())
具体用户可以关注知识星球: 查看全部
更新:
制作好了一个接口,用户可以直接调用。
数据来源与集思录。
获取 排除满足强赎天数剩余N天的可转债,排除强赎可转债。
比如:DAY=4 ,那么假设强赎满足天数为15天,那么返回市场上强赎强赎倒数天数大于4天的可转债,即返回小于或者等于11天以下的转债。把满足条件还差4天的转债排除掉了,当然,已经公告强赎的也会被排除。
import requests
URL = 'http://11.11.11.11/api/redeem/'
# DAY 强赎倒数剩余天数小于 DAY (4)天, 已经公告强赎的也是被排除的
DAY = 4
SIGN = '私信星主获取' # sign和以前一致
data = {'day': DAY,
'sign': SIGN}
r = requests.post(URL, data=data)
print(r.json())
具体用户可以关注知识星球:
PTrade使用教程 新手入门
股票 • 李魔佛 发表了文章 • 0 个评论 • 18914 次浏览 • 2021-03-18 08:55
记录一下曾经的入门经验与使用心得:
好像PTrade有几个版本,本人使用的界面如下,基于python写交易策略和回测:
1. 仿真系统的回测可以在交易时间运行,交易系统的回测无法在交易时间运行回测。
2. 在研究板块中,API函数带有研究字样的,可以直接使用,不需要import 导入任何库。比如:#获取当日的股票池
g.stock_list = get_Ashares(g.current_date)可以自己使用。
而get_history(70, '1d', ['close','volume'], g.stock_list, fq='dypre', include=False)
没有带研究字样的,是无法直接在研究板块使用,只能在回测或者实盘使用。
3. 内置的python版本是:
'3.5.1 (default, Nov 1 2016, 01:53:03) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]'
也就是无法使用fstring的方式格式化字符串
name='jack'
a=f'{name}'
4. log.debug log.error 等调试标记符不会有任何输出,bug!
只能使用log.info 或者print输出,还害我调试了半天,以为程序哪里的问题,导致我的输出不显示。
PTrade新手入门教程 二
需要开通Ptrade的朋友,可以扫描二维码开户,并可开通PTrade交易功能。
股票费率万分之一,转债十万分之二。
非诚勿扰。
原创文章,转载请注明出处
https://www.30daydo.com/article/44151
查看全部
记录一下曾经的入门经验与使用心得:
好像PTrade有几个版本,本人使用的界面如下,基于python写交易策略和回测:
1. 仿真系统的回测可以在交易时间运行,交易系统的回测无法在交易时间运行回测。
2. 在研究板块中,API函数带有研究字样的,可以直接使用,不需要import 导入任何库。比如:
#获取当日的股票池可以自己使用。
g.stock_list = get_Ashares(g.current_date)
而
get_history(70, '1d', ['close','volume'], g.stock_list, fq='dypre', include=False)没有带研究字样的,是无法直接在研究板块使用,只能在回测或者实盘使用。
3. 内置的python版本是:
'3.5.1 (default, Nov 1 2016, 01:53:03) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]'
也就是无法使用fstring的方式格式化字符串
name='jack'
a=f'{name}'
4. log.debug log.error 等调试标记符不会有任何输出,bug!
只能使用log.info 或者print输出,还害我调试了半天,以为程序哪里的问题,导致我的输出不显示。
PTrade新手入门教程 二
需要开通Ptrade的朋友,可以扫描二维码开户,并可开通PTrade交易功能。
股票费率万分之一,转债十万分之二。
非诚勿扰。

原创文章,转载请注明出处
https://www.30daydo.com/article/44151
a股券商开户 万1免五 没有最低消费
券商万一免五 • 李魔佛 发表了文章 • 0 个评论 • 14984 次浏览 • 2021-03-07 17:51
不过之前还找到一家万一免五的,没有最低费率,用多少算多少,比如买了1000元股票,那么费率只有1000*万分之一,等于1分钱,略等于不用钱哈。
优势杠杆的。
需要的点击下面链接即可开户: 注意:当前默认的免五已经取消了,需要开通量化交易权限后可以进行免五操作。
开通ptrade和qmt量化交易接口的条件,入金30万,过3天左右可以开通,开通后可以免五!
交割单:
心动不,赶紧心动吧。
该券商也支持同花顺客户端登录,做量化的使用easytrader也可以友好支持。
如果有疑问,可以扫码咨询。备注:开户
查看全部
可转债如何配债
股票 • 李魔佛 发表了文章 • 0 个评论 • 14555 次浏览 • 2019-03-29 16:24
1、如果你在登记日也就是12月11日收盘时还持有一定数量歌尔声学正股的话,那么你在配债日也就是12月12日就会看到账户里有相应数量的歌尔配债。注意这里的单位是张,如图,
由于我只有800股歌尔声学,因此获得了13张配债,1张对应100元,这时双击它,左侧出现了卖出菜单,价格和配债代码都自动填好了,输入13张或者点击全部,然后点“卖出”。(需要注意的是:有些券商这里是买入。)
2、不管是卖出还是买入,然后检查下委托情况和扣款情况,如下图:
可以看到我已经被扣款1300元,这样就算成功完成了这次的13张配债.
可转债低佣金开户,沪市转债费率百分之二,全市场最低。
有兴趣的朋友可以扫描开户:
查看全部
1、如果你在登记日也就是12月11日收盘时还持有一定数量歌尔声学正股的话,那么你在配债日也就是12月12日就会看到账户里有相应数量的歌尔配债。注意这里的单位是张,如图,
由于我只有800股歌尔声学,因此获得了13张配债,1张对应100元,这时双击它,左侧出现了卖出菜单,价格和配债代码都自动填好了,输入13张或者点击全部,然后点“卖出”。(需要注意的是:有些券商这里是买入。)
2、不管是卖出还是买入,然后检查下委托情况和扣款情况,如下图:
可以看到我已经被扣款1300元,这样就算成功完成了这次的13张配债.
可转债低佣金开户,沪市转债费率百分之二,全市场最低。
有兴趣的朋友可以扫描开户:

可转债价格分布堆叠图 绘制 可视化 python+pyecharts
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 13482 次浏览 • 2019-01-30 10:59
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:
点击查看大图
如果我用下面的图形就可以看出规律:
点击查看大图
横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
那么如何使用代码实现呢?from setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)
result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)
# 确定价格的范围
value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))
ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1
retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1
retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1
retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1
retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1
bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)
如果没有安装pyecharts,需要用pip安装即可。
原创文章
转载请注明出处:
https://www.30daydo.com/article/400
查看全部
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:
点击查看大图
如果我用下面的图形就可以看出规律:
点击查看大图
横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
那么如何使用代码实现呢?
from setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)
result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)
# 确定价格的范围
value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))
ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1
retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1
retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1
retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1
retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1
bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)
如果没有安装pyecharts,需要用pip安装即可。
原创文章
转载请注明出处:
https://www.30daydo.com/article/400
QMT文件读写限制绕过
QMT • 李魔佛 发表了文章 • 0 个评论 • 133 次浏览 • 2026-10-20 19:33
而其QMT测试客户端在10月13日已经开始限制了。
简单测试了一下:
报错日子一看,FileIO已经没有权限写入。写入文件路径为 "D:\github\input.csv"
不过只要我把目录路径改成相对路径:"input.csv" , 数据是可以被写入且读取的。
这个路径是QMT安装目录下的子目录bin.x64,比如我的是: D:\tool\gjzq_qmt_simulation\bin.x64
这样就轻松绕过读写限制了。
其实上面的绝对路径的读取文件也是没有任何问题的,只是无法写入而已。
需要写入的话就使用相对路径。
网络的话,测试端使用requests请求一切正常,并没有限制。所以传递数据的时候使用API传给QMT访问是没有问题的。
QMT本地持久化
如果不想使用本地来存储,QMT系统提供了
save_py_key(key, value) 和 get_py_key(key)
两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。QMT系统提供了 save_py_key(key, value) 和 get_py_key(key) 两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。
函数说明:
save_py_key(key, value):保存数据
key :要保存的关键字, str 类型
value :要保存的值, str 类型
返回: errid (错误id,0表示成功), errmsg (错误信息,成功时为空字符串)
示例: errid, errmsg = save_py_key('关键字', '值')
get_py_key(key):读取数据
key :要读取的关键字, str 类型
返回: value (返回的值, str 类型), errid , errmsg
示例: value, errid, errmsg = get_py_key('关键字')
注意事项:
单字段长度限制为5000字符(英文1个字符,中文2个字符)。
该功能适用于在QMT系统对文件读写和网络连接进行限制后,替代本地文件存储中间变量的方案。
附测试使用代码:
# encoding:gbk
import json
def server_kv_store():
key = 'positions'
v = [{'symbol': '123456.SZ','base_pirce':100},{'symbol': '123457.SZ','base_pirce':200}]
kv = { key: json.dumps(v)}
# 保存键值对
print('保存数据',kv)
errid, errmsg = save_py_key(key, kv[key])
if errid != 0:
print("Failed to save key-value: ", errmsg)
return
print('保存成功,读取数据')
value, errid, errmsg = get_py_key(key)
if errid!=0:
print("Failed to get key-value: ", errmsg)
return
jvalue = json.loads(value)
print('读取数据', jvalue)
def init(ContextInfo):
# read_io()
# network_io()
server_kv_store()
def handlebar(ContextInfo):
pass
在测试客户端上测试通过。
value的参数类型是str,所以dict,list这些类型需要json.dump序列化一下,不然会报错。
不同券商遇到的问题不同,到时QMT实盘客户端也可能有不同的限制,可评论留言。
关注公众号: 查看全部
而其QMT测试客户端在10月13日已经开始限制了。
简单测试了一下:
报错日子一看,FileIO已经没有权限写入。写入文件路径为 "D:\github\input.csv"
不过只要我把目录路径改成相对路径:"input.csv" , 数据是可以被写入且读取的。
这个路径是QMT安装目录下的子目录bin.x64,比如我的是: D:\tool\gjzq_qmt_simulation\bin.x64
这样就轻松绕过读写限制了。
其实上面的绝对路径的读取文件也是没有任何问题的,只是无法写入而已。
需要写入的话就使用相对路径。
网络的话,测试端使用requests请求一切正常,并没有限制。所以传递数据的时候使用API传给QMT访问是没有问题的。
QMT本地持久化
如果不想使用本地来存储,QMT系统提供了
save_py_key(key, value) 和 get_py_key(key)
两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。
QMT系统提供了 save_py_key(key, value) 和 get_py_key(key) 两个函数,用于将策略运行过程中的中间变量持久化存储到券商服务端数据库中,数据是加密保存的。
函数说明:
save_py_key(key, value):保存数据
key :要保存的关键字, str 类型
value :要保存的值, str 类型
返回: errid (错误id,0表示成功), errmsg (错误信息,成功时为空字符串)
示例: errid, errmsg = save_py_key('关键字', '值')
get_py_key(key):读取数据
key :要读取的关键字, str 类型
返回: value (返回的值, str 类型), errid , errmsg
示例: value, errid, errmsg = get_py_key('关键字')
注意事项:
单字段长度限制为5000字符(英文1个字符,中文2个字符)。
该功能适用于在QMT系统对文件读写和网络连接进行限制后,替代本地文件存储中间变量的方案。
附测试使用代码:
# encoding:gbk
import json
def server_kv_store():
key = 'positions'
v = [{'symbol': '123456.SZ','base_pirce':100},{'symbol': '123457.SZ','base_pirce':200}]
kv = { key: json.dumps(v)}
# 保存键值对
print('保存数据',kv)
errid, errmsg = save_py_key(key, kv[key])
if errid != 0:
print("Failed to save key-value: ", errmsg)
return
print('保存成功,读取数据')
value, errid, errmsg = get_py_key(key)
if errid!=0:
print("Failed to get key-value: ", errmsg)
return
jvalue = json.loads(value)
print('读取数据', jvalue)
def init(ContextInfo):
# read_io()
# network_io()
server_kv_store()
def handlebar(ContextInfo):
pass
在测试客户端上测试通过。
value的参数类型是str,所以dict,list这些类型需要json.dump序列化一下,不然会报错。
不同券商遇到的问题不同,到时QMT实盘客户端也可能有不同的限制,可评论留言。
关注公众号:
国金证券, 国投证券 QMT 的IO文件功能被禁止
QMT • 李魔佛 发表了文章 • 0 个评论 • 886 次浏览 • 2026-10-12 09:14
下面是券商的公告:
系统预留信息
【重要】内置Python策略功能调整
2026-10-08 00:00:00
[重要]尊敬的投资者:
为进一步规范迅投QMT系统功能,我部近期将对有关功能模块进行调整,具体如下:
一、关闭内置Python策略文件读写功能
涉及本地文件读写的功能(包括但不限于open()、read()、write()及相关第三方库)均无法使用。
二、关闭内置Python策略外部网络连接功能
涉及策略发起的网络连接(包括但不限于HTTP、TCP、UDP等)、局域网或本机数据库连接(包括但不限于MYSQL、Redis、SQLite等)以及与局域网内其他设备进行网络通信、网络IP地址与网络端口的连接及涉及上述的相关三方库均会被禁止。
三、取消登录页的独立交易选项
本次功能升级,将会一并取消登录页的独立交易选项,如您的系统界面仍有此按钮,请尽快在本次升级完成后登录我司官网下载最新客户端。
本次升级将于10月23日完成,使用内置python,且不与外部进行任何交互的策略不受上述调整影响。
这次整治, 是因为有些人利用QMT,miniQMT 售卖策略. 但他们不是给你源码, 因为源码卖出是一次性的. 他们为了更长远的割韭菜, 它们提供的参数配置, 需要你去开户, 然后使用QMT账号, 连接他们的系统, 你只能修改一些策略参数, 定制化程度比较低, 策略同质化比较严重, 如果资金量大的人, 还很容易被他们内部收割. 比如你设置的参数止盈是涨幅5%, 他们内部可以设置另一个策略, 止盈为4.5% , 就可以在你之前出货.
目前已知的黑平台有云飞量化, 禄得lude.cc 这些, 这次也是因为它们导致miniQMT被查封的. 查看全部
下面是券商的公告:
系统预留信息
【重要】内置Python策略功能调整
2026-10-08 00:00:00
[重要]尊敬的投资者:
为进一步规范迅投QMT系统功能,我部近期将对有关功能模块进行调整,具体如下:
一、关闭内置Python策略文件读写功能
涉及本地文件读写的功能(包括但不限于open()、read()、write()及相关第三方库)均无法使用。
二、关闭内置Python策略外部网络连接功能
涉及策略发起的网络连接(包括但不限于HTTP、TCP、UDP等)、局域网或本机数据库连接(包括但不限于MYSQL、Redis、SQLite等)以及与局域网内其他设备进行网络通信、网络IP地址与网络端口的连接及涉及上述的相关三方库均会被禁止。
三、取消登录页的独立交易选项
本次功能升级,将会一并取消登录页的独立交易选项,如您的系统界面仍有此按钮,请尽快在本次升级完成后登录我司官网下载最新客户端。
本次升级将于10月23日完成,使用内置python,且不与外部进行任何交互的策略不受上述调整影响。
这次整治, 是因为有些人利用QMT,miniQMT 售卖策略. 但他们不是给你源码, 因为源码卖出是一次性的. 他们为了更长远的割韭菜, 它们提供的参数配置, 需要你去开户, 然后使用QMT账号, 连接他们的系统, 你只能修改一些策略参数, 定制化程度比较低, 策略同质化比较严重, 如果资金量大的人, 还很容易被他们内部收割. 比如你设置的参数止盈是涨幅5%, 他们内部可以设置另一个策略, 止盈为4.5% , 就可以在你之前出货.
目前已知的黑平台有云飞量化, 禄得lude.cc 这些, 这次也是因为它们导致miniQMT被查封的.
国信证券iquant(QMT) 相比其他券商 有什么优势?
QMT • 李魔佛 发表了文章 • 0 个评论 • 583 次浏览 • 2026-09-05 16:17
国信QMT(相对于其他券商的QMT软件的优势),PS: 国信的QMT叫iquant,界面加了一些功能。
一、国信QMT历史数据更丰富,下载不受限制,从股票上市就有,其他券商只有最近三年的历史数据。
二、国信QMT的L1(tick)行情数据免费使用,支持盘口五档以及分笔数据,其他券商只有三档。
三、国信QMT支持算法交易以及云服务器运行,其他券商不支持。
五、国信QMT支持多点登录,也就是多个电脑同事登录一个账号,其他券商不支持。
六、国信QMT申请实盘简单,开户后T+1申请实盘,不用邮寄资料,其他券商需要客户邮寄资料。
七、国信是头部券商,全国各地都有营业部,客户办理高端业务,临柜方便,国信证券提供量化技术支持服务。
国信有miniQMT,可以拿去获取数据,回测,但是不能去下单。
查看全部
国信QMT(相对于其他券商的QMT软件的优势),PS: 国信的QMT叫iquant,界面加了一些功能。
一、国信QMT历史数据更丰富,下载不受限制,从股票上市就有,其他券商只有最近三年的历史数据。
二、国信QMT的L1(tick)行情数据免费使用,支持盘口五档以及分笔数据,其他券商只有三档。
三、国信QMT支持算法交易以及云服务器运行,其他券商不支持。
五、国信QMT支持多点登录,也就是多个电脑同事登录一个账号,其他券商不支持。
六、国信QMT申请实盘简单,开户后T+1申请实盘,不用邮寄资料,其他券商需要客户邮寄资料。
七、国信是头部券商,全国各地都有营业部,客户办理高端业务,临柜方便,国信证券提供量化技术支持服务。
国信有miniQMT,可以拿去获取数据,回测,但是不能去下单。
华泰QMT下载 | 华泰支持迅投QMT了
QMT • 李魔佛 发表了文章 • 0 个评论 • 636 次浏览 • 2026-08-03 10:41
华泰迅投QMT系统是专门为专业交易客户打造的集合策略投研、交易执行、行情展示、风控管理为一体的综合投研交易终端。策略研究包括数据管理、策略研究、策略风控等功能;支持组合交易、算法交易、对冲交易、机构风格下单等高效的交易功能,满足不同投资者的多样化交易需求。
QMT下载地址:
https://inst.htsc.com/helpOnline?productId=60&moduleCode=1
它支持自定义编程模块,可以自己编程下单。
接口文档:https://qmt.ptradeapi.com
查看全部
华泰迅投QMT系统是专门为专业交易客户打造的集合策略投研、交易执行、行情展示、风控管理为一体的综合投研交易终端。策略研究包括数据管理、策略研究、策略风控等功能;支持组合交易、算法交易、对冲交易、机构风格下单等高效的交易功能,满足不同投资者的多样化交易需求。
QMT下载地址:
https://inst.htsc.com/helpOnline?productId=60&moduleCode=1
它支持自定义编程模块,可以自己编程下单。
接口文档:https://qmt.ptradeapi.com
miniQMT停用后,外部调用QMT内部函数的路子
QMT • 李魔佛 发表了文章 • 0 个评论 • 1326 次浏览 • 2026-07-02 08:56
但办法总比困难多,其中一个方法是在QMT里开一个HTTP的REST API服务,外部可以调用这个HTTP API,达到下单,撤单,查询持仓,获取行情等所有在QMT下所需要的功能。
目前QMT内置的python版本为3.6.8,你可以在里面安装各种第三方web框架,fastapi,django,flask等。而QMT原来内置了tornado,就不需要额外安装其他第三方库了。文末提供完整源码地址。
导入所需要的库
from tornado.web import Application, RequestHandler, HTTPError
from tornado.ioloop import IOLoop
程序核心就是在QMT的init函数里面就启动我们的HTTP服务,端口PORT随意。
PORT = 10086
ACCOUNT_ID = '你的QMT账号'
def init(ContextInfo):
try:
ContextInfo.accountID = ACCOUNT_ID
app = make_app()
app.ContextInfo = ContextInfo
app.accountID = ContextInfo.accountID
app.listen(PORT, address='0.0.0.0') # 如果只在本地网络,可以设置为127.0.0.1
logger.info(f"QMT HTTP Server 启动于 http://0.0.0.0:{PORT} (全部API已加载)")
IOLoop.current().start()
except Exception as e:
logger.exception(f"server start failed: {e}")
make_app里提供的注册路由。
============= 路由注册 =============
def make_app():
return Application([
# 原有兼容路由
(r"/api/holding", HoldingHandler),
(r"/api/money/total", TotalMoneyHandler),
(r"/api/money/available", AvailableMoneyHandler),
(r"/api/order/buy", BuyHandler),
(r"/api/order/sell", SellHandler),
(r"/api/order/deal", DealHandler),
..... 省略若干
# 数据查询
(r"/api/data/stock_name", StockNameHandler),
(r"/api/data/open_date", OpenDateHandler),
(r"/api/data/last_volume", LastVolumeHandler),
(r"/api/data/bar_timetag", BarTimetagHandler),
(r"/api/data/tick_timetag", TickTimetagHandler),
(r"/api/data/sector", SectorHandler),
(r"/api/data/industry", IndustryHandler),
(r"/api/data/stock_list_in_sector", StockListInSectorHandler),
(r"/api/data/history_data", HistoryDataHandler),
(r"/api/data/market_data", MarketDataHandler),
(r"/api/data/market_data_ex", MarketDataExHandler),
(r"/api/data/full_tick", FullTickHandler),
每个API实现一个原QMT的函数,所以有非常多的API端点。
当然这些函数我都让AI帮我对着QMT的文档实现的。
接口文档:https://qmt.ptradeapi.com/QMT_Python_API_Doc.html
然后FullTickHandler的实现如下:
# ContextInfo.get_full_tick() - 获取分笔数据
class FullTickHandler(BaseHandler):
def post(self):
data = json.loads(self.request.body)
stocks = data.get('stocks', '')
if not stocks:
raise HTTPError(400, "need args stocks")
code_list = [s.strip() for s in stocks.split(',')]
ret = safe_call(self.ctx().get_full_tick, code_list)
if not ret:
raise HTTPError(500, "获取分笔行情失败")
self.write(json.dumps(ret, ensure_ascii=False, default=str))
这里核心就是执行QMT的get_full_tick,把数据作为response返回。请求使用POST,传入股票代码,返回股票tick数据。
在QMT里启动后,等待外部程序调用。
上面是把完整代码复制到QMT里,然后在实盘里面启动。
然后在你外部的程序里面写个简单的HTTP请求,就能调用QMT里面的API了。
如果你的电脑有公网IP,还可以不同电脑去远程调用QMT里面的函数,
这里加入一个任意TOKEN,和QMT里面一致就行,这样请求的header带上,避免其他人调用你的API操作你账号。如果只在本地运行,可以把最开始的监听地址0.0.0.0改为127.0.0.1
TOKEN = "123456789"
class QMTClient:
def __init__(self, base_url="http://127.0.0.1:10086"):
self.base = base_url
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json; charset=utf-8"})
self.session.headers.update({"X-Token": TOKEN})
def _req(self, method, path, **kwargs):
url = f"{self.base}{path}"
try:
resp = self.session.request(method, url, timeout=10, **kwargs)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
return {"error": str(e), "status_code": getattr(e.response, 'status_code', 500)}
def get_full_tick(self, stocks):
return self._req('POST', f'/api/data/full_tick', json={
"stocks": stocks})
client = QMTClient()
print(client.get_full_tick('600000.SH'))
client = QMTClient()
print(client.get_full_tick('600000.SH'))
QMT里可以看到对应的调用记录
外部程序的返回的结果:
然后按葫芦画瓢,让AI对着文档把剩余的函数都实现了即可。
比如要下单功能,就实现
# passorder(23) - 买入下单(封装passorder)
class BuyHandler(BaseHandler):
def post(self):
try:
data = json.loads(self.request.body)
stock = data['stock']
price = float(data['price'])
volume = int(data['volume'])
pr_type = data.get('prType', 11)
order_ref = passorder(23, 1101, self.acc(), stock, pr_type, price, volume, 'qmt', 2, self.ctx())
self.write(json.dumps({
"status": "success", "action": "buy", "stock": stock,
"order_ref": str(order_ref) if order_ref else"unknown"
}, ensure_ascii=False))
except Exception as e:
logger.exception("买入下单异常")
raise HTTPError(400, f"下单失败: {str(e)}")
然后在外部你的策略代码里面加入:
client = QMTClient()
client.buy_stock("600000.SZ", 6.80, 100)
即可完成下单,然后可以通过API查询持仓,获取最新状态。这样就不用把你策略嵌入到QMT里。
完整源码在github: https://github.com/Rockyzsu/QMT,(不确定是否AI封装的函数全部正确,会偶尔更新一下)
或者关注公众号"可转债量化分析",后台回复关键字:QMT封装
查看全部
但办法总比困难多,其中一个方法是在QMT里开一个HTTP的REST API服务,外部可以调用这个HTTP API,达到下单,撤单,查询持仓,获取行情等所有在QMT下所需要的功能。
目前QMT内置的python版本为3.6.8,你可以在里面安装各种第三方web框架,fastapi,django,flask等。而QMT原来内置了tornado,就不需要额外安装其他第三方库了。文末提供完整源码地址。
导入所需要的库
from tornado.web import Application, RequestHandler, HTTPError
from tornado.ioloop import IOLoop
程序核心就是在QMT的init函数里面就启动我们的HTTP服务,端口PORT随意。
PORT = 10086
ACCOUNT_ID = '你的QMT账号'
def init(ContextInfo):
try:
ContextInfo.accountID = ACCOUNT_ID
app = make_app()
app.ContextInfo = ContextInfo
app.accountID = ContextInfo.accountID
app.listen(PORT, address='0.0.0.0') # 如果只在本地网络,可以设置为127.0.0.1
logger.info(f"QMT HTTP Server 启动于 http://0.0.0.0:{PORT} (全部API已加载)")
IOLoop.current().start()
except Exception as e:
logger.exception(f"server start failed: {e}")
make_app里提供的注册路由。
============= 路由注册 =============
def make_app():
return Application([
# 原有兼容路由
(r"/api/holding", HoldingHandler),
(r"/api/money/total", TotalMoneyHandler),
(r"/api/money/available", AvailableMoneyHandler),
(r"/api/order/buy", BuyHandler),
(r"/api/order/sell", SellHandler),
(r"/api/order/deal", DealHandler),
..... 省略若干
# 数据查询
(r"/api/data/stock_name", StockNameHandler),
(r"/api/data/open_date", OpenDateHandler),
(r"/api/data/last_volume", LastVolumeHandler),
(r"/api/data/bar_timetag", BarTimetagHandler),
(r"/api/data/tick_timetag", TickTimetagHandler),
(r"/api/data/sector", SectorHandler),
(r"/api/data/industry", IndustryHandler),
(r"/api/data/stock_list_in_sector", StockListInSectorHandler),
(r"/api/data/history_data", HistoryDataHandler),
(r"/api/data/market_data", MarketDataHandler),
(r"/api/data/market_data_ex", MarketDataExHandler),
(r"/api/data/full_tick", FullTickHandler),
每个API实现一个原QMT的函数,所以有非常多的API端点。
当然这些函数我都让AI帮我对着QMT的文档实现的。
接口文档:https://qmt.ptradeapi.com/QMT_Python_API_Doc.html
然后FullTickHandler的实现如下:
# ContextInfo.get_full_tick() - 获取分笔数据
class FullTickHandler(BaseHandler):
def post(self):
data = json.loads(self.request.body)
stocks = data.get('stocks', '')
if not stocks:
raise HTTPError(400, "need args stocks")
code_list = [s.strip() for s in stocks.split(',')]
ret = safe_call(self.ctx().get_full_tick, code_list)
if not ret:
raise HTTPError(500, "获取分笔行情失败")
self.write(json.dumps(ret, ensure_ascii=False, default=str))
这里核心就是执行QMT的get_full_tick,把数据作为response返回。请求使用POST,传入股票代码,返回股票tick数据。
在QMT里启动后,等待外部程序调用。
上面是把完整代码复制到QMT里,然后在实盘里面启动。
然后在你外部的程序里面写个简单的HTTP请求,就能调用QMT里面的API了。
如果你的电脑有公网IP,还可以不同电脑去远程调用QMT里面的函数,
这里加入一个任意TOKEN,和QMT里面一致就行,这样请求的header带上,避免其他人调用你的API操作你账号。如果只在本地运行,可以把最开始的监听地址0.0.0.0改为127.0.0.1
TOKEN = "123456789"
class QMTClient:
def __init__(self, base_url="http://127.0.0.1:10086"):
self.base = base_url
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json; charset=utf-8"})
self.session.headers.update({"X-Token": TOKEN})
def _req(self, method, path, **kwargs):
url = f"{self.base}{path}"
try:
resp = self.session.request(method, url, timeout=10, **kwargs)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
return {"error": str(e), "status_code": getattr(e.response, 'status_code', 500)}
def get_full_tick(self, stocks):
return self._req('POST', f'/api/data/full_tick', json={
"stocks": stocks})
client = QMTClient()
print(client.get_full_tick('600000.SH'))
client = QMTClient()
print(client.get_full_tick('600000.SH'))
QMT里可以看到对应的调用记录
外部程序的返回的结果:
然后按葫芦画瓢,让AI对着文档把剩余的函数都实现了即可。
比如要下单功能,就实现
# passorder(23) - 买入下单(封装passorder)
class BuyHandler(BaseHandler):
def post(self):
try:
data = json.loads(self.request.body)
stock = data['stock']
price = float(data['price'])
volume = int(data['volume'])
pr_type = data.get('prType', 11)
order_ref = passorder(23, 1101, self.acc(), stock, pr_type, price, volume, 'qmt', 2, self.ctx())
self.write(json.dumps({
"status": "success", "action": "buy", "stock": stock,
"order_ref": str(order_ref) if order_ref else"unknown"
}, ensure_ascii=False))
except Exception as e:
logger.exception("买入下单异常")
raise HTTPError(400, f"下单失败: {str(e)}")
然后在外部你的策略代码里面加入:
client = QMTClient()
client.buy_stock("600000.SZ", 6.80, 100)
即可完成下单,然后可以通过API查询持仓,获取最新状态。这样就不用把你策略嵌入到QMT里。
完整源码在github: https://github.com/Rockyzsu/QMT,(不确定是否AI封装的函数全部正确,会偶尔更新一下)
或者关注公众号"可转债量化分析",后台回复关键字:QMT封装
miniQMT要被暂停使用了吗
QMT • 李魔佛 发表了文章 • 0 个评论 • 990 次浏览 • 2026-07-01 18:26
国X证券的通知:
但其他券商没有收到这个消息,所以其他券商依然能够正常使用。
从反馈的情况来看,是国X证券大面积推广这个miniQMT,导致同行反馈,被举报导致的。
其他规模不大的券商目前来看依然是安全的。
查看全部
华泰证券支持QMT和Ptrade吗?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 1248 次浏览 • 2026-04-28 17:21
已更新。
目前华泰新增支持QMT。门槛入金50w。
### 2026-05 发布的 ####不支持。
目前为止,华泰没有Ptrade和QMT,华泰的量化平台用的是Matic。
好多AI读取的垃圾语料, 污染了返回结果.
里面有个模块MQuant。用于编写量化程序,支持python和C++
matic文档:
https://github.com/Rockyzsu/matic.git
需要开通的朋友可以扫码关注公众号,获取开通联系方式:
查看全部
已更新。
目前华泰新增支持QMT。门槛入金50w。
### 2026-05 发布的 ####不支持。
目前为止,华泰没有Ptrade和QMT,华泰的量化平台用的是Matic。
好多AI读取的垃圾语料, 污染了返回结果.
里面有个模块MQuant。用于编写量化程序,支持python和C++
matic文档:
https://github.com/Rockyzsu/matic.git
需要开通的朋友可以扫码关注公众号,获取开通联系方式:

东莞证券ptrade的编程功能模块被移除了
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1875 次浏览 • 2025-11-23 13:17
本来门槛不太高,作为备用也是不错的.
也不知道上面领导怎么想的. 把编程模块移走了.
目前就剩ptrade上内置的一些基础功能
无法通过python编程实现自己的自定义策略.
有点可惜.
查看全部
东北证券QMT miniQMT (NET专业版)万0.854免5
QMT • 李魔佛 发表了文章 • 0 个评论 • 4861 次浏览 • 2025-10-16 23:05
东北证券的qmt名称叫NET专业版。
东北证券的QMT支持python和vba 两种语言。
开通后可加入量化技术群。
扫码联系开通。 查看全部
申万宏源 Ptrade / QMT/miniQMT 免5 开通
QMT • 李魔佛 发表了文章 • 0 个评论 • 3046 次浏览 • 2025-08-07 19:01
支持QMT,miniQMT和Ptrade。
量化功能应有尽有,是目前为止为数不多的有miniQMT的免5券商。
费率低,ETF,可转债均为万0.5
线上开户,需要的朋友可以扫码联系开通。
查看全部
QMT获取北交所市场代码
QMT • 李魔佛 发表了文章 • 0 个评论 • 2723 次浏览 • 2025-02-21 11:30
现在的券商只要你开了科创板,可以直接开通北交所,不再需要20交易日,50w的要求。
QMT获取北交所代码:
运行输出结果:
需要开通量化api权限的券商,可以扫码关注并咨询 查看全部
江海证券支持QMT,miniQMT,且低门槛开通
QMT • 李魔佛 发表了文章 • 0 个评论 • 5981 次浏览 • 2025-02-12 00:46
江海证券有限公司于2003年12月15日在哈尔滨市市场监督管理局登记成立。法定代表人孙名扬,公司经营范围包括证券经纪,证券承销与保荐,证券投资咨询,证券自营等。
这logo看起来有点像银河呢。
江海证券现有分支机构75家,其中17家分公司,58家营业部,遍布北京、上海、广州、深圳、厦门、青岛、大连、成都、武汉、长沙、合肥及黑龙江省内等主要城市,形成了“覆盖龙江、辐射沿海、布局全国”的业务发展格局。
不过上面的是2018年的数据,最新的可能会少一些。因为现在很多营业部都更加注重线上业务。也就是通过线上就可以开通账号。
目前江海证券能够开通量化QMT,和miniQMT的自动化交易权限。
下载地址:
江海证券QMT实盘_实盘_1.0.0.36190.exe
或者直接到官网:
https://www.jhzq.com.cn/main/home/software/index.shtml
选择QMT下载即可
江海证券也支持无限易量化平台。
需要的可以咨询公众号: 查看全部
江海证券有限公司于2003年12月15日在哈尔滨市市场监督管理局登记成立。法定代表人孙名扬,公司经营范围包括证券经纪,证券承销与保荐,证券投资咨询,证券自营等。
这logo看起来有点像银河呢。
江海证券现有分支机构75家,其中17家分公司,58家营业部,遍布北京、上海、广州、深圳、厦门、青岛、大连、成都、武汉、长沙、合肥及黑龙江省内等主要城市,形成了“覆盖龙江、辐射沿海、布局全国”的业务发展格局。
不过上面的是2018年的数据,最新的可能会少一些。因为现在很多营业部都更加注重线上业务。也就是通过线上就可以开通账号。
目前江海证券能够开通量化QMT,和miniQMT的自动化交易权限。
下载地址:
江海证券QMT实盘_实盘_1.0.0.36190.exe
或者直接到官网:
https://www.jhzq.com.cn/main/home/software/index.shtml
选择QMT下载即可
江海证券也支持无限易量化平台。
需要的可以咨询公众号:
QMT获取市场可转债代码
可转债 • 李魔佛 发表了文章 • 0 个评论 • 2716 次浏览 • 2024-11-14 11:12
#encoding:gbk
def init(ContextInfo):
pass
def handlebar(ContextInfo):
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
print(ContextInfo.get_stock_list_in_sector('沪深转债', realtime))
欢迎关注公众号:可转债量化分析 查看全部
可转债现金替代策略 | QMT | Ptrade
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 2651 次浏览 • 2024-10-15 11:05
适合大资金,求稳。
挑选低价格的AAA可转债,比如 正股是 银行,高分红的国企股,比如 大秦铁路的转债,大秦转债等,且到期收益为正。作为标的池。
然后 先 在标的池里挑选出一个价格最低的转债,1/3 仓位 买入,其余仓位买入银华日利。
程序每分钟监控。或者不用那么频繁,可以设置每小时,每天都可以。
如果转债价格下跌了X,就卖出银华日利(1/10仓位),买入转债; (这里仓位随意举例)
如果转债价格上涨了Y,就卖出转债(1/5仓位),买入银华日利;(这里仓位随意举例)
一般AAA的大规模转债,其波动比较小,很少会遇到趋势上涨。 所以大部分的时间是做有波动的高抛低吸。
但,一旦遇到趋势上涨,或者突破,那么按照策略 会不断卖出转债;
一旦转债仓位为0,就可以在标的池买入另外一只标的(1/3仓位),从而继续下一轮的高抛低吸。
如果转债价格一直跌,但由于AAA的转债有保底,且有回售,转股,下修等各种手段,来兜底,
所以一般遇到跌幅行情,下跌不会超过10%,所以策略可以一直在卖出银华日利,买入转债;
如果中途,出现了其他好的标的,你需要手动交易,那么可以手动卖出银华日利或者可转债,腾出仓位,来操作。
也就是这个策略的可转债,纯粹当做现金来替代来使用。
接着就是使用QMT和Ptrade实现。
待续............
查看全部
适合大资金,求稳。
挑选低价格的AAA可转债,比如 正股是 银行,高分红的国企股,比如 大秦铁路的转债,大秦转债等,且到期收益为正。作为标的池。
然后 先 在标的池里挑选出一个价格最低的转债,1/3 仓位 买入,其余仓位买入银华日利。
程序每分钟监控。或者不用那么频繁,可以设置每小时,每天都可以。
如果转债价格下跌了X,就卖出银华日利(1/10仓位),买入转债; (这里仓位随意举例)
如果转债价格上涨了Y,就卖出转债(1/5仓位),买入银华日利;(这里仓位随意举例)
一般AAA的大规模转债,其波动比较小,很少会遇到趋势上涨。 所以大部分的时间是做有波动的高抛低吸。
但,一旦遇到趋势上涨,或者突破,那么按照策略 会不断卖出转债;
一旦转债仓位为0,就可以在标的池买入另外一只标的(1/3仓位),从而继续下一轮的高抛低吸。
如果转债价格一直跌,但由于AAA的转债有保底,且有回售,转股,下修等各种手段,来兜底,
所以一般遇到跌幅行情,下跌不会超过10%,所以策略可以一直在卖出银华日利,买入转债;
如果中途,出现了其他好的标的,你需要手动交易,那么可以手动卖出银华日利或者可转债,腾出仓位,来操作。
也就是这个策略的可转债,纯粹当做现金来替代来使用。
接着就是使用QMT和Ptrade实现。
待续............

QMT获取不到行情,一般是什么原因?或者获取行情有中断的情况
QMT • 李魔佛 发表了文章 • 0 个评论 • 3205 次浏览 • 2024-09-29 10:27
或者你获取的5档tick行情,但是你的行情菜单那里,选择的是 最新价,这样你也是无法获取到 5档tick数据的。
然后还有一个问题,如果你用get_market_data 或者get_market_data_ex 这个函数,获取的股票数量很多(比如全市场的股票),那么第一次的启动数据会非常的慢,并且你的内存消耗非常大,整个QMT像死机了一样。
如何解决? 下回分解
查看全部
QMT的handlebar设置成一分钟周期的时候,运行是3秒一次的
QMT • 李魔佛 发表了文章 • 0 个评论 • 3583 次浏览 • 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 个评论 • 4193 次浏览 • 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和代写量化策略,可以关注公众号:
低门槛入金2W开通QMT miniQMT,股票费率免5,0.1元起
券商万一免五 • 李魔佛 发表了文章 • 0 个评论 • 4058 次浏览 • 2024-08-31 14:29
而且费率是直接可以调到 万0.754,免五,0.1元起。 简直比万一免五还要低!
目前属于活动期间才有的低费率。
需要开户的,可以联系公众号,开户后有QMT技术支持交流群
######### 最新更新, 此券商活动已停止 #############
查看全部
国信iquant requests 爬虫 获取数据 还有使用 tushare,akshare 无法连接,提示超时
QMT • 李魔佛 发表了文章 • 0 个评论 • 3780 次浏览 • 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 个评论 • 3617 次浏览 • 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 个评论 • 6632 次浏览 • 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,低门槛,低费率,还有技术支持群!
QMT获取持仓信息报错:AttributeError: 'NoneType' object has no attribute 'request_id'
QMT • 李魔佛 发表了文章 • 0 个评论 • 2866 次浏览 • 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 个评论 • 3537 次浏览 • 2024-05-29 12:02
成交了多少量,就融券多少量。达到指标即可停止。
代写量化程序,可以关注公众号,后台联系。 价格比QMT官网低的多了。实战性选手,选过N多QMT,ptrade实盘代码。
查看全部
迅投官网的实例代码好多问题,惨不忍睹
QMT • 李魔佛 发表了文章 • 0 个评论 • 2536 次浏览 • 2024-05-12 16:55
还有更多的缩进的问题。
pep8的规范早已经不用tab来做缩进,而是用4个空格。
之前的文章里面也提到了,可以在qmt的配置文件里面改的。不过在UI上是不提供修改的地方。
https://www.30daydo.com/article/44602
查看全部
以前喜欢用C替代ContextInfo,现在改过去了,又有部分改的不完整。
还有更多的缩进的问题。
pep8的规范早已经不用tab来做缩进,而是用4个空格。
之前的文章里面也提到了,可以在qmt的配置文件里面改的。不过在UI上是不提供修改的地方。
https://www.30daydo.com/article/44602
QMT里定时任务运行时间操作定时任务的间隔,会怎么样?
QMT • 李魔佛 发表了文章 • 0 个评论 • 3004 次浏览 • 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秒之后打印出来。
使用量化程序获取ETF的成分股与实时净值
QMT • 李魔佛 发表了文章 • 0 个评论 • 3116 次浏览 • 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 个评论 • 2637 次浏览 • 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 个评论 • 2987 次浏览 • 2024-04-01 13:38
qmt下载完数据之后,get_market_data_ex依然还是获取不到数据。
其实主要数据没有刷新。
只需要你手动关闭QMT,再打开一次就好了。
反正呢,这些问题,QMT也不会告诉你,要靠自己摸索了。
欢迎收藏网站哦! 查看全部
QMT每次自动升级,都会把改过的配置文件给覆盖掉
QMT • 李魔佛 发表了文章 • 0 个评论 • 3229 次浏览 • 2024-03-31 14:23
感觉设计模式有问题。
本来我配置了缩进用的4个空格,(这是pep8的标准好吧)
而qmt默认是用tab做缩进。
导致从vs code或者pycharm上的代码迁移迁移过来qmt的编辑器,你按tab键,是制表符,而不是4个空格。
运行或者回测就会报错。
每次升级都把我的配置给改了。
难道不覆盖config文件不行吗? 每次类似全量升级,一点点bug fix都在全量升级
查看全部
不同券商的数据质量简单对比:国金QMT vs 国信QMT(iquant)
QMT • 李魔佛 发表了文章 • 0 个评论 • 6113 次浏览 • 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 !')
























































































































