通知设置 新通知
akshare 官网地址
李魔佛 发表了文章 • 0 个评论 • 70 次浏览 • 2023-05-25 21:50
不明白为啥百度前面几页都显示不到akshare的官网。对这个搜索结果实在有点无语。
ptrade 微信通知
李魔佛 发表了文章 • 0 个评论 • 753 次浏览 • 2022-09-20 10:29
所以情况多了,经常会忘记,手动登录进去重启。导致策略没有运行。
所以办法1,在盘前函数加入 微信通知,在交易日,如果盘前(8:30分左右),没有收到微信提醒,那么就需要即使登录到ptrade进行手动重启。
代码如下:def notify(content=''):
send_qywx(
'微信id', '微信key', 'agent', info=content,
touser= '你的微信名字',
)
def before_trading_start(context, data):
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
notify('Ptrade 盘前运行{}'.format(now))
差不多这样就可以了。
不过笔者一般会使用另外一个种方式,因为如果哪一天没有收到,意味这ptrade没有起来,但你没有收到,你也就忘了这么一回事。 所以笔者的做法是,正常情况下不推送,而在ptrade不启动的时候才推送到微信。
下回更新。待续
# 继续更新
每天盘前,ptrade会到mysql插入一条数据,比如当天的日期
然后有个程序每天定时去读取mysql,如果读不到数据,就发送数据给微信即可。
class DBSelector():
'''
数据库选择类
'''
def get_engine(self):
from sqlalchemy import create_engine
try:
engine = create_engine(
'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USER, PASSWORD, MYSQL_HOST, MYSQL_PORT, MYSQL_DB))
except Exception as e:
log.error(e)
return None
return engine
def get_mysql_conn(self, db):
import pymysql
try:
conn = pymysql.connect(host=MYSQL_HOST, port=MYSQL_PORT, user=USER, password=PASSWORD, db=db,
charset='utf8')
except Exception as e:
log.error(e)
return None
else:
return conn
def main():
now = datetime.datetime.now()
if not now.weekday():
print('not week day')
return
db = DBSelector()
conn = db.get_mysql_conn('ptrade')
cursor = conn.cursor()
sql_str = 'select count(*) from `ptrade_runing_status` where `date`=%s limit 1'
date = now.strftime('%Y-%m-%d')
cursor.execute(sql_str, (date,))
result = cursor.fetchone()
if result[0] == 0:
send_message_via_wechat('{} ptrade没有启动!'.format(now))
if __name__=='__main__':
main()
查看全部
所以情况多了,经常会忘记,手动登录进去重启。导致策略没有运行。
所以办法1,在盘前函数加入 微信通知,在交易日,如果盘前(8:30分左右),没有收到微信提醒,那么就需要即使登录到ptrade进行手动重启。
代码如下:
def notify(content=''):
send_qywx(
'微信id', '微信key', 'agent', info=content,
touser= '你的微信名字',
)
def before_trading_start(context, data):
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
notify('Ptrade 盘前运行{}'.format(now))
差不多这样就可以了。
不过笔者一般会使用另外一个种方式,因为如果哪一天没有收到,意味这ptrade没有起来,但你没有收到,你也就忘了这么一回事。 所以笔者的做法是,正常情况下不推送,而在ptrade不启动的时候才推送到微信。
下回更新。待续
# 继续更新
每天盘前,ptrade会到mysql插入一条数据,比如当天的日期
然后有个程序每天定时去读取mysql,如果读不到数据,就发送数据给微信即可。
class DBSelector():
'''
数据库选择类
'''
def get_engine(self):
from sqlalchemy import create_engine
try:
engine = create_engine(
'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USER, PASSWORD, MYSQL_HOST, MYSQL_PORT, MYSQL_DB))
except Exception as e:
log.error(e)
return None
return engine
def get_mysql_conn(self, db):
import pymysql
try:
conn = pymysql.connect(host=MYSQL_HOST, port=MYSQL_PORT, user=USER, password=PASSWORD, db=db,
charset='utf8')
except Exception as e:
log.error(e)
return None
else:
return conn
def main():
now = datetime.datetime.now()
if not now.weekday():
print('not week day')
return
db = DBSelector()
conn = db.get_mysql_conn('ptrade')
cursor = conn.cursor()
sql_str = 'select count(*) from `ptrade_runing_status` where `date`=%s limit 1'
date = now.strftime('%Y-%m-%d')
cursor.execute(sql_str, (date,))
result = cursor.fetchone()
if result[0] == 0:
send_message_via_wechat('{} ptrade没有启动!'.format(now))
if __name__=='__main__':
main()

Ptrade的回测程序是在本地运行还是远程服务器? 关闭ptrade后原来运行的回测还可以继续运行吗?
回复李魔佛 回复了问题 • 1 人关注 • 1 个回复 • 1019 次浏览 • 2022-09-11 21:07
Ptrade与QMT 获取可转债基础数据,溢价率,剩余规模,评级,双低,是否强赎
李魔佛 发表了文章 • 0 个评论 • 1213 次浏览 • 2022-09-08 22:25
搜索接口文档,关键字 可转债 , 只有可怜的一个接口。并且这个接口还是最近才提供的。
基本没有可转债的其他基础数据。
比如 溢价率,剩余规模,评级,双低,到期,强赎。
笔者也为了方便,跨平台,把数据调用抽离出来,写成可以调用 接口的方式。
用的post请求方式。
这样无论是ptrade还是qmt,还是平时写的选股web页面, 都可以直接调用同一个数据源。 而你只需要维护一个数据数据源。
需要接口的,可以加入星球 或者 开通ptrade/QMT 的同时 获取。
查看全部
花了1小时用django快速写了个可转债实时系统
李魔佛 发表了文章 • 0 个评论 • 684 次浏览 • 2022-09-07 08:08
用django快速搭了个页面给他
点击查看大图
数据是实时选出来的。当时帮他做的回测收益率也是很高,主要回撤控制得很好。
本来想用gin写,发现后台的dataframe还有这要找go下对应的库,避免计算出错,还是用会python吧(-。-) 查看全部
ptrade和qmt的内置代码编辑器,哪个比较好用?
李魔佛 发表了文章 • 0 个评论 • 845 次浏览 • 2022-09-05 11:24
答:都十分渣,半斤八两。更裸手在记事本写代码差不多的感觉。 尤其对于新人,经常可能会因为一些拼写错误,换行等问题,折腾一天,才能找到原因,至少pycharm对没有引用的变量是变灰的,语法错误是红的,快速帮助定位错误。(我自己就亲身经历过这种调试惨案,太惨痛。)
查看全部
答:都十分渣,半斤八两。更裸手在记事本写代码差不多的感觉。 尤其对于新人,经常可能会因为一些拼写错误,换行等问题,折腾一天,才能找到原因,至少pycharm对没有引用的变量是变灰的,语法错误是红的,快速帮助定位错误。(我自己就亲身经历过这种调试惨案,太惨痛。)
从零开始 手撸一个回测框架 (以可转债双低,低溢价为例)
李魔佛 发表了文章 • 0 个评论 • 1024 次浏览 • 2022-09-01 18:39
Mysql 数据
下面是代码主框架,目前通过之前优矿的导出的csv数据 ,计算 各个因子。 通过不同权重评分,进行轮动。class DataFeed:
def __init__(self):
self.csv_path = CSV_PATH
self.position = {}
self.HighValue = 0
self.Start_Cash = 1000000 # 初始资金
self.MyCash = self.Start_Cash
self.Withdraw = 0
self.daily_netvalue =
self.current_day = 0
self.PosValue = 0
self.threshold = 0 # 阈值
self.HighValue = self.Start_Cash
self.date_list, self.source = self.feed()
self.day_count = 0
def unpossibile(self, df, date):
# 剔除当日涨停的转债,买不入
raise_limited_dict = {
'2022-04-08': ['127057', ],
'2022-07-27': ['127065', ],
'2022-07-28': ['127065', ],
}
target_list = raise_limited_dict.get(date, None)
if target_list is None:
return df
return df.drop(index=target_list, axis=1)
def feed(self):
df = pd.read_csv(self.csv_path,
encoding='utf8',
dtype={'tickerEqu': str, 'tickerBond': str, 'secID_x': str},
)
del df['Unnamed: 0']
df['tradeDate'] = pd.to_datetime(df['tradeDate'], format='%Y-%m-%d')
df = df.set_index('tradeDate')
date_set = set(df.index.tolist())
date_list = list(map(lambda x: x.strftime('%Y-%m-%d'), date_set))
date_list.sort()
return date_list, df
def filters(self, df, today):
# 过滤条件,可添加多个条件
df = self.unpossibile(df, today)
return df
def logprint(self, current):
log.info('当前日期{}'.format(current))
def run(self):
for current in self.date_list:
if current < START_DATE or current > END_DATE:
continue
if self.day_count % FREQ != 0:
self.get_daily_netvalue(current)
else:
self.handle_data(current)
self.day_count += 1
self.after_trade()
双低和低溢价选债轮动:
上面是主要框架代码, 根据数据来驱动交易。 可以根据不同的时间日期进行回测交易。不同持有个数,不同轮动功能天数。【完整代码可以常见 知识星球】
运行: python main.py
运行后会自动保存一个excel文件:
并且可以生成收益率曲线图:
完整代码与数据可以参考星球代码:
查看全部
Mysql 数据
下面是代码主框架,目前通过之前优矿的导出的csv数据 ,计算 各个因子。 通过不同权重评分,进行轮动。
class DataFeed:
def __init__(self):
self.csv_path = CSV_PATH
self.position = {}
self.HighValue = 0
self.Start_Cash = 1000000 # 初始资金
self.MyCash = self.Start_Cash
self.Withdraw = 0
self.daily_netvalue =
self.current_day = 0
self.PosValue = 0
self.threshold = 0 # 阈值
self.HighValue = self.Start_Cash
self.date_list, self.source = self.feed()
self.day_count = 0
def unpossibile(self, df, date):
# 剔除当日涨停的转债,买不入
raise_limited_dict = {
'2022-04-08': ['127057', ],
'2022-07-27': ['127065', ],
'2022-07-28': ['127065', ],
}
target_list = raise_limited_dict.get(date, None)
if target_list is None:
return df
return df.drop(index=target_list, axis=1)
def feed(self):
df = pd.read_csv(self.csv_path,
encoding='utf8',
dtype={'tickerEqu': str, 'tickerBond': str, 'secID_x': str},
)
del df['Unnamed: 0']
df['tradeDate'] = pd.to_datetime(df['tradeDate'], format='%Y-%m-%d')
df = df.set_index('tradeDate')
date_set = set(df.index.tolist())
date_list = list(map(lambda x: x.strftime('%Y-%m-%d'), date_set))
date_list.sort()
return date_list, df
def filters(self, df, today):
# 过滤条件,可添加多个条件
df = self.unpossibile(df, today)
return df
def logprint(self, current):
log.info('当前日期{}'.format(current))
def run(self):
for current in self.date_list:
if current < START_DATE or current > END_DATE:
continue
if self.day_count % FREQ != 0:
self.get_daily_netvalue(current)
else:
self.handle_data(current)
self.day_count += 1
self.after_trade()
双低和低溢价选债轮动:
上面是主要框架代码, 根据数据来驱动交易。 可以根据不同的时间日期进行回测交易。不同持有个数,不同轮动功能天数。【完整代码可以常见 知识星球】
运行: python main.py
运行后会自动保存一个excel文件:
并且可以生成收益率曲线图:
完整代码与数据可以参考星球代码:
python获取通达信可转债日线和分时数据
李魔佛 发表了文章 • 0 个评论 • 2564 次浏览 • 2022-08-28 10:41
除了优矿,还有哪些可以获取可转债日线,甚至分时tick数据呢?当然笔者压箱底里面还有很多可用数据源的。本文就简单介绍其中一个,下通达信数据源。
安装
使用pip安装第三方库pytdxpip install pytdx
分时数据
下面6行python代码, 就可以获取通达信的可转债分时数据。from pytdx.hq import TdxHq_API
api = TdxHq_API()
with api.connect('119.147.212.81', 7709):
data = api.get_security_bars(7, 0, '123045', 0, 240) # 123045 为转债代码 ,240 为获取 240个转债数据
df = api.to_df(data)
df=df.sort_values('datetime')
如果需要遍历当前最新可转债代码,需要结合前面的文章。【注意这代码会定期更新,因网站架构或者字段是不定时变动】
不过前面的接口只能读取800条数据,以一天240条数据计算,只能读取2天多的数据量,对于需要更多数据的朋友来说,肯定不够的。或者有一个办法,把上面代码写成定时任务,就可以每天收盘后自动存储对应的数据。
如果需要更多的历史数据,那么可以使用pytdx的另外一个功能,那就是使用python读取通达信本地数据文件。
先用通达信同步1分钟(或5分钟)数据到本地.
选择沪深京分钟线,当然,其他数据你也可以选择。勾选一分钟线数据或者5分钟线数据,还有日期。不过这里日期会有限制,只能下载100天的1分钟线,或者500天的5分钟线。所以如果长期需要这个数据,你可以每隔一段时间下载一次。
数据保存路径:通达信安装目录的 vipdoc 子目录比如我的通达信客户端安装在 c:\new_tdx 下,
即
c:\new_tdx\vipdoc\sz\lday\ 下是深圳的日k线数据
c:\new_tdx\vipdoc\sh\lday\ 下是上海的日k线数据
c:\new_tdx\vipdoc\sh\minline\ 下是上海的分钟线数据
c:\new_tdx\vipdoc\sz\minline\ 下是深圳的分钟线数据
如果你需要更久的历史数据,可以到网上找找,下载下来后按照下面代码读取即可。 from pytdx.reader import TdxMinBarReader
path='/home/xda/Downloads/sz128014.lc1'
reader = TdxMinBarReader()
df = reader.get_df(path)
#df.to_excel('tick.xlsx') # 导出为excel
得到dataframe对象后,接着可以保存为excel,数据库都很简单了。一条语句的事情。
可转债日线数据
当然,能够获取到分钟数据,对于日线数据更加不在话下了。日线数据并没有日期限制,想下多少有多少。api = TdxHq_API()
api = api.connect('119.147.212.81', 7709)
data=api.get_k_data('123045', '2020-05-01', '2022-08-26') # 123045 为可转债代码,可以替换任意代码
data.to_excel('k-line.xlsx')
如果想获取正股或者其他股票数据,只需要把代码替换成正股股票代码即可。
如果分钟数据还不满足,还可以使用更小粒度的tick数据。下回有空再继续介绍,敬请关注。
欢迎关注公众号 查看全部
除了优矿,还有哪些可以获取可转债日线,甚至分时tick数据呢?当然笔者压箱底里面还有很多可用数据源的。本文就简单介绍其中一个,下通达信数据源。
安装
使用pip安装第三方库pytdx
pip install pytdx
分时数据
下面6行python代码, 就可以获取通达信的可转债分时数据。
from pytdx.hq import TdxHq_API
api = TdxHq_API()
with api.connect('119.147.212.81', 7709):
data = api.get_security_bars(7, 0, '123045', 0, 240) # 123045 为转债代码 ,240 为获取 240个转债数据
df = api.to_df(data)
df=df.sort_values('datetime')
如果需要遍历当前最新可转债代码,需要结合前面的文章。【注意这代码会定期更新,因网站架构或者字段是不定时变动】
不过前面的接口只能读取800条数据,以一天240条数据计算,只能读取2天多的数据量,对于需要更多数据的朋友来说,肯定不够的。或者有一个办法,把上面代码写成定时任务,就可以每天收盘后自动存储对应的数据。
如果需要更多的历史数据,那么可以使用pytdx的另外一个功能,那就是使用python读取通达信本地数据文件。
先用通达信同步1分钟(或5分钟)数据到本地.
选择沪深京分钟线,当然,其他数据你也可以选择。勾选一分钟线数据或者5分钟线数据,还有日期。不过这里日期会有限制,只能下载100天的1分钟线,或者500天的5分钟线。所以如果长期需要这个数据,你可以每隔一段时间下载一次。
数据保存路径:通达信安装目录的 vipdoc 子目录
比如我的通达信客户端安装在 c:\new_tdx 下,
即
c:\new_tdx\vipdoc\sz\lday\ 下是深圳的日k线数据
c:\new_tdx\vipdoc\sh\lday\ 下是上海的日k线数据
c:\new_tdx\vipdoc\sh\minline\ 下是上海的分钟线数据
c:\new_tdx\vipdoc\sz\minline\ 下是深圳的分钟线数据
如果你需要更久的历史数据,可以到网上找找,下载下来后按照下面代码读取即可。
from pytdx.reader import TdxMinBarReader
path='/home/xda/Downloads/sz128014.lc1'
reader = TdxMinBarReader()
df = reader.get_df(path)
#df.to_excel('tick.xlsx') # 导出为excel
得到dataframe对象后,接着可以保存为excel,数据库都很简单了。一条语句的事情。
可转债日线数据
当然,能够获取到分钟数据,对于日线数据更加不在话下了。日线数据并没有日期限制,想下多少有多少。
api = TdxHq_API()
api = api.connect('119.147.212.81', 7709)
data=api.get_k_data('123045', '2020-05-01', '2022-08-26') # 123045 为可转债代码,可以替换任意代码
data.to_excel('k-line.xlsx')
如果想获取正股或者其他股票数据,只需要把代码替换成正股股票代码即可。
如果分钟数据还不满足,还可以使用更小粒度的tick数据。下回有空再继续介绍,敬请关注。

欢迎关注公众号
6行python代码 获取通达信的可转债分时数据
李魔佛 发表了文章 • 0 个评论 • 1242 次浏览 • 2022-08-27 14:33
api = TdxHq_API()
with api.connect('119.147.212.81', 7709):
data = api.get_security_bars(7, 0, '123045', 0, 240) # 123045 为转债代码 ,240 为获取 240个转债数据
df = api.to_df(data)
df=df.sort_values('datetime')
点击查看大图
如果需要遍历当前最新可转债代码(集思录),需要结合前面的文章。 查看全部
Ptrade 逆回购+自动申购新股可转债
李魔佛 发表了文章 • 0 个评论 • 861 次浏览 • 2022-08-24 20:03
本站所有代码均经过实盘验证。# ptrade软件-量化-回测 里,新建策略,复制全文粘贴进去,周期选分钟,再到交易里新增交易
import time
def reverse_repurchase(context):
cash = context.portfolio.cash
amount = int(cash/1000)*10
log.info(amount)
order('131810.SZ', -1*amount) # 深圳逆回购,
def ipo(context):
ipo_stocks_order()
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
run_daily(context, reverse_repurchase, '14:57')
run_daily(context, ipo, '13:30')
def before_trading_start(context, data):
pass
def handle_data(context, data):
pass
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
上面代码设定在13:30分申购新股,新债;
在14:57分申购深圳逆回购R-001
喜欢的朋友拿去,欢迎转载。
欢迎关注公众号
查看全部
本站所有代码均经过实盘验证。
# ptrade软件-量化-回测 里,新建策略,复制全文粘贴进去,周期选分钟,再到交易里新增交易
import time
def reverse_repurchase(context):
cash = context.portfolio.cash
amount = int(cash/1000)*10
log.info(amount)
order('131810.SZ', -1*amount) # 深圳逆回购,
def ipo(context):
ipo_stocks_order()
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
run_daily(context, reverse_repurchase, '14:57')
run_daily(context, ipo, '13:30')
def before_trading_start(context, data):
pass
def handle_data(context, data):
pass
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
上面代码设定在13:30分申购新股,新债;
在14:57分申购深圳逆回购R-001
喜欢的朋友拿去,欢迎转载。

欢迎关注公众号
Ptrade 获取当天可转债代码列表
李魔佛 发表了文章 • 0 个评论 • 745 次浏览 • 2022-08-22 18:46
可以在开盘的时候获取所有可转债列表。
def initialize(context):
run_daily(context, get_trade_cb_list, "9:25")
def before_trading_start(context, data):
# 每日清空,避免取到昨日市场代码表
g.trade_cb_list =
def handle_data(context, data):
pass
# 获取当天可交易的可转债代码列表
def get_trade_cb_list(context):
cb_list = get_cb_list()
cb_snapshot = get_snapshot(cb_list)
# 代码有行情快照并且交易状态不在暂停交易、停盘、长期停盘、退市状态的判定为可交易代码
g.trade_cb_list = [cb_code for cb_code in cb_list if
cb_snapshot.get(cb_code, {}).get("trade_status") not in
[None, "HALT", "SUSP", "STOPT", "DELISTED"]]
log.info("当天可交易的可转债代码列表为:%s" % g.trade_cb_list)
如果需要获取可转债溢价率,评级,剩余规模,强赎等数据,可以调用我之前提供的接口。
需要的可以关注个人星球和公众号。
欢迎关注公众号
查看全部
可以在开盘的时候获取所有可转债列表。
def initialize(context):
run_daily(context, get_trade_cb_list, "9:25")
def before_trading_start(context, data):
# 每日清空,避免取到昨日市场代码表
g.trade_cb_list =
def handle_data(context, data):
pass
# 获取当天可交易的可转债代码列表
def get_trade_cb_list(context):
cb_list = get_cb_list()
cb_snapshot = get_snapshot(cb_list)
# 代码有行情快照并且交易状态不在暂停交易、停盘、长期停盘、退市状态的判定为可交易代码
g.trade_cb_list = [cb_code for cb_code in cb_list if
cb_snapshot.get(cb_code, {}).get("trade_status") not in
[None, "HALT", "SUSP", "STOPT", "DELISTED"]]
log.info("当天可交易的可转债代码列表为:%s" % g.trade_cb_list)
如果需要获取可转债溢价率,评级,剩余规模,强赎等数据,可以调用我之前提供的接口。
需要的可以关注个人星球和公众号。

欢迎关注公众号
Ptrade里面的 持久化 (pickle)要求 报错:
李魔佛 发表了文章 • 0 个评论 • 669 次浏览 • 2022-08-22 17:42
为什么要做持久化处理
服务器异常、策略优化等诸多场景,都会使得正在进行的模拟盘和实盘策略存在中断后再重启的需求,但是一旦交易中止后,策略中存储在内存中的全局变量就清空了,因此通过持久化处理为量化交易保驾护航必不可少。
量化框架持久化处理
使用pickle模块保存股票池、账户信息、订单信息、全局变量g定义的变量等内容。
注意事项:
框架会在before_trading_start(隔日开始)、handle_data、after_trading_end事件后触发持久化信息更新及保存操作;
券商升级/环境重启后恢复交易时,框架会先执行策略initialize函数再执行持久化信息恢复操作。
如果持久化信息保存有策略定义的全局对象g中的变量,将会以持久化信息中的变量覆盖掉initialize函数中初始化的该变量。
1 全局变量g中不能被序列化的变量将不会被保存。
您可在initialize中初始化该变量时名字以'__'开头;
2 涉及到IO(打开的文件,实例化的类对象等)的对象是不能被序列化的;
3 全局变量g中以'__'开头的变量为私有变量,持久化时将不会被保存;
示例代码:class Test(object):
count = 5
def print_info(self):
self.count += 1
log.info("a" * self.count)
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
# 初始化无法被序列化类对象,并赋值为私有变量,落地持久化信息时跳过保存该变量
g.__test_class = Test()
def handle_data(context, data):
# 调用私有变量中定义的方法
g.__test_class.print_info()
其实官方文档说了这么多,实际意思就是 类和涉及IO的 变量 不能序列化,导致不能在g中作为全局变量,如果要作为全局变量,需要 用2个前下划线__ 命名,比如 g.__db = Bond()
class Bond:
pass
不然就会报错:
_pickle.PickingError: Can't pick <class 'IOEngine.user_module : attribute loopup
欢迎关注公众号 查看全部
为什么要做持久化处理
服务器异常、策略优化等诸多场景,都会使得正在进行的模拟盘和实盘策略存在中断后再重启的需求,但是一旦交易中止后,策略中存储在内存中的全局变量就清空了,因此通过持久化处理为量化交易保驾护航必不可少。
量化框架持久化处理
使用pickle模块保存股票池、账户信息、订单信息、全局变量g定义的变量等内容。
注意事项:
框架会在before_trading_start(隔日开始)、handle_data、after_trading_end事件后触发持久化信息更新及保存操作;
券商升级/环境重启后恢复交易时,框架会先执行策略initialize函数再执行持久化信息恢复操作。
如果持久化信息保存有策略定义的全局对象g中的变量,将会以持久化信息中的变量覆盖掉initialize函数中初始化的该变量。
1 全局变量g中不能被序列化的变量将不会被保存。
您可在initialize中初始化该变量时名字以'__'开头;
2 涉及到IO(打开的文件,实例化的类对象等)的对象是不能被序列化的;
3 全局变量g中以'__'开头的变量为私有变量,持久化时将不会被保存;
示例代码:
class Test(object):
count = 5
def print_info(self):
self.count += 1
log.info("a" * self.count)
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
# 初始化无法被序列化类对象,并赋值为私有变量,落地持久化信息时跳过保存该变量
g.__test_class = Test()
def handle_data(context, data):
# 调用私有变量中定义的方法
g.__test_class.print_info()
其实官方文档说了这么多,实际意思就是 类和涉及IO的 变量 不能序列化,导致不能在g中作为全局变量,如果要作为全局变量,需要 用2个前下划线__ 命名,比如 g.__db = Bond()
class Bond:
pass
不然就会报错:
_pickle.PickingError: Can't pick <class 'IOEngine.user_module : attribute loopup

欢迎关注公众号
虚拟机 云服务器 运行qmt 方案
李魔佛 发表了文章 • 0 个评论 • 1251 次浏览 • 2022-08-20 17:17
众所周知,部分券商(国盛证券)限制了虚拟机登录QMT。
比如在vmare中安装了QMT,可以在QMT的信息里面看到:
点击查看大图
比如上面的截图, 如果和实体机的设备信息做一个对比,可以看到,虚拟机下的QMT的硬盘序列号(红框的位置) 是空的,而实体物理机下,红框的硬盘序列号 是有内容的。 所以一个办法是尝试修改这个硬盘序列号。
或者换一个支持虚拟机的券商。其实这个限制是券商端定制的功能,部分券商并没有限制虚拟机禁止登陆QMT的。
比如国金证券的QMT,可以在虚拟机或者云服务器上登录。费率也可以万一免五,参考文章:
http://www.30daydo.com/article/44479 查看全部
点击查看大图
众所周知,部分券商(国盛证券)限制了虚拟机登录QMT。
比如在vmare中安装了QMT,可以在QMT的信息里面看到:
点击查看大图
比如上面的截图, 如果和实体机的设备信息做一个对比,可以看到,虚拟机下的QMT的硬盘序列号(红框的位置) 是空的,而实体物理机下,红框的硬盘序列号 是有内容的。 所以一个办法是尝试修改这个硬盘序列号。
或者换一个支持虚拟机的券商。其实这个限制是券商端定制的功能,部分券商并没有限制虚拟机禁止登陆QMT的。
比如国金证券的QMT,可以在虚拟机或者云服务器上登录。费率也可以万一免五,参考文章:
http://www.30daydo.com/article/44479
通过mini qmt xtdata获取tick数据 python代码
李魔佛 发表了文章 • 0 个评论 • 1920 次浏览 • 2022-08-17 18:03
from xtquant import xtdata
xtdata.download_history_data(code, period=period, start_time=start_time, end_time=end_time)
data = xtdata.get_local_data(field_list=, stock_code=, period=period, count=10)
result_list = data df = pd.DataFrame(result_list)
df['time_str'] = df['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0))
return df
上面python代码传入一个代码,和初试时间,需要的周期数据(分钟,秒,日等),就可以返回一个dataframe格式的数据了。
欢迎关注公众号 查看全部
def get_tick(code, start_time, end_time, period='tick'):
from xtquant import xtdata
xtdata.download_history_data(code, period=period, start_time=start_time, end_time=end_time)
data = xtdata.get_local_data(field_list=, stock_code=
, period=period, count=10)
result_list = data
df = pd.DataFrame(result_list)
df['time_str'] = df['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0))
return df
上面python代码传入一个代码,和初试时间,需要的周期数据(分钟,秒,日等),就可以返回一个dataframe格式的数据了。

欢迎关注公众号
Ptrade下单接口 order,order_target, order_value,order_target_value的区别
李魔佛 发表了文章 • 0 个评论 • 848 次浏览 • 2022-08-11 23:57
接口
order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
所以其他几个接口都是对order的封装。
order接口的逻辑:order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台
欢迎关注公众号 查看全部
order_target 接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口
order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
所以其他几个接口都是对order的封装。
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台

欢迎关注公众号
Ptrade抢新上市的可转债
李魔佛 发表了文章 • 0 个评论 • 697 次浏览 • 2022-08-11 10:20
自己写的包在 PTrade 里如何使用的方法有吗?
李魔佛 发表了文章 • 0 个评论 • 778 次浏览 • 2022-08-08 03:28
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。
欢迎关注公众号 查看全部
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。

欢迎关注公众号
ptrade支持文件的读写吗,Excel 文件可以读写吗
李魔佛 发表了文章 • 0 个评论 • 816 次浏览 • 2022-08-08 00:01
当前支持 csv,xlsx,txt,pkl 等文件的读取,需要手动将对应文件上传到研究环境中,
然后在回测中使用 get_research_path()+”文件名”获取文件路径后进行读取(见下图),
回写文件类似,可使用 pd.to_csv()等函数存储在研究环境指定目录下。
值得注意的是,当前支持单个文件最大为 50M
模型每天都会更新的,权重文件,能上传吗?
可以,注意文件大小的限制。
欢迎关注公众号 查看全部
优矿使用的python版本
李魔佛 发表了文章 • 0 个评论 • 724 次浏览 • 2022-08-07 08:22
从底层来看它的报错信息:
它是使用python2.7
可是异常操作,却可以使用python3的语法
try:
....
except Exception as e:
.....
所以有些地方还是得要注意一下 py2和py3的区别
比如py2的字典默认顺序是无序的。(这个有一次调试一个bug耗费了一两个小时,结果发现用了字典,取key,结果发现key的顺序全部是乱的,py3从3.6开始字典的key是有序的)
查看全部