source_code = """
def init(context):
g.is_fired = True
log.info("初始化,仅在策略第一次运行时执行")
def before_trading(context):
date = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
log.info('{} 盘前运行'.format(date))
def open_auction(context,bar_dict):
date = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
log.info('{} 集合竞价后运行'.format(date))
def handle_bar(context,bar_dict):
date = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
log.info('{} 盘中运行'.format(date))
if g.is_fired:
odr_id = order('000001.SZ',100)
g.is_fired = False
def on_order(context,odr):
log.info('委托状态更新推送')
log.info(odr)
def on_trade(context,trade):
log.info('成交推送')
log.info(trade)
def after_trading(context):
date = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
log.info('{} 盘后运行'.format(date))
"""
btest = research_strategy(
source_code=source_code,start_date='20230801',end_date='20230801',
capital_base=float(1000000),frequency='MINUTE',stock_market='STOCK',
benchmark='000300.SH',plot=True
)
包括设置基准,手续费,滑点,初始持仓,等设置性函数,可参考帮助-股票API-设置函数,这里不在赘述
用于存储策略信息(context.run_info),账户持仓数据(context.portfolio),自定义全局变量
source_code = """
def init(context):
context.fired=True
log.info(context.run_info)
log.info(context.portfolio)
log.info(context.fired)
def handle_bar(context,bar_dict):
if context.fired:
odr_id = order('000001.SZ',100)
context.fired = False
log.info(context.run_info)
log.info(context.portfolio)
log.info(context.fired)
log.info(context.portfolio.positions) #输出看起来像个列表,实际类似于字典
log.info(context.portfolio.stock_account.positions)
log.info(context.portfolio.positions['000001.SZ'])
log.info(context.portfolio.stock_account.positions['000001.SZ'])
"""
btest = research_strategy(
source_code=source_code,start_date='20230801',end_date='20230801',
capital_base=float(1000000),frequency='MINUTE',stock_market='STOCK',
benchmark='000300.SH',plot=True
)
和context的功能类似,存储全局变量,自定义的全局变量推荐存在g里,避免将系统全局变量覆盖
source_code = """
def init(context):
g.abc=123
def handle_bar(context,bar_dict):
print(g.abc)
"""
btest = research_strategy(
source_code=source_code,start_date='20230801',end_date='20230801',
capital_base=float(1000000),frequency='MINUTE',stock_market='STOCK',
benchmark='000300.SH',plot=True
)
on_order函数推送,或使用get_order/get_orders/get_open_orders函数查询
on_trade函数推送,或使用get_tradelogs函数查询
source_code = """
def init(context):
g.fired = True
def handle_bar(context,bar_dict):
if g.fired:
log.info(bar_dict['000001.SZ'])
log.info(bar_dict['000001.SZ'].datetime)
log.info(bar_dict['000001.SZ'].close)
g.fired=False
"""
btest = research_strategy(
source_code=source_code,start_date='20230801',end_date='20230801',
capital_base=float(1000000),frequency='MINUTE',stock_market='STOCK',
benchmark='000300.SH',plot=True
)
调用方式:history(symbol_list, fields, bar_count, fre_step, skip_paused = False, fq = 'pre', is_panel=0)
取当前K线之前的{bar_dict}根K线的数据
source_code = '''
def init(context):
pass
def before_trading(context):
ohlcv = history(['000001.SZ','600519.SH'], ['open','high','low','close','volume'], 5, '1d', skip_paused = False, fq = 'pre', is_panel=0)
log.info(ohlcv)
ohlcv = history(['000001.SZ','600519.SH'], ['open','high','low','close','volume'], 5, '1d', skip_paused = False, fq = 'pre', is_panel=1)
log.info(ohlcv)
log.info(ohlcv.to_frame())
'''
btest = research_strategy(
source_code=source_code,start_date='20230801',end_date='20230801',
capital_base=float(1000000),frequency='MINUTE',stock_market='STOCK',
benchmark='000300.SH',plot=True
)
这边只讲简单的使用方法,具体可以参考官方文档继续学习sqlalchemy文档
q = query(
concept_classification#表名
)
run_query(q) #取整张表太大了,不进行演示
q = query(
concept_classification.symbol,#表名.字段
concept_classification.date,
concept_classification.concept
)
相当于SQL中的where
run_query(
q.filter(
concept_classification.symbol=='300033.SZ',
concept_classification.date>'20230201'
)
)
run_query(
q.filter(
concept_classification.symbol.in_(['300033.SZ','600519.SH']),
concept_classification.date=='20230201'
)
)
run_query(
q.filter(
concept_classification.symbol=='300033.SZ',
concept_classification.date>'20230201'
).limit(10)
)
run_query(
q.filter(
concept_classification.symbol=='300033.SZ',
concept_classification.date>'20230201'
).order_by(
concept_classification.date.desc()
).limit(10)
)
run_query(
q.filter(
concept_classification.symbol=='300033.SZ',
concept_classification.date>'20230201'
).order_by(
concept_classification.date.asc()
).limit(10)
)
run_query(
q.filter(
concept_classification.symbol=='300033.SZ',
concept_classification.date>'20230201'
).order_by(
concept_classification.date
).limit(10)
)
调用方式: get_fundamentals(query_object, date=None, statDate=None, latest=False)
#获取全市场2022年报资产负债表中的总资产数据,仅取合并报表
data = get_fundamentals(
query(
balance.symbol,
balance.report_date,
balance.stat_date,
balance.total_assets
).filter(
balance.reporttypecode == 'HB'
),
statDate = '2022q4'
)
data
#获取全市场2023年2月1日全市场股票最近一期资产负债表中的总资产数据,取最新报告数据
data = get_fundamentals(
query(
balance.symbol,
balance.date,
balance.report_date,
balance.stat_date,
balance.total_assets
),
date = '20230201',
latest = True
)
data
跟据绝对数量下单
跟据目标值下单,可能会下0股,导致日志出现warn
下单成功,返回订单委托id,失败则返回None
在回测中,以市价单买入涨停股或者卖出跌停股,订单会作为失败处理,而限价单会挂着
source_code = '''
def init(context):
g.fired = True
def handle_bar(context,bar_dict):
if g.fired:
order_id = order('000001.SZ',100,bar_dict['000001.SZ'].close*0.98)
cancel_order(order_id)
g.fired = False
def on_order(context,odr):
print(odr)
'''
btest = research_strategy(
source_code=source_code,start_date='20230801',end_date='20230801',
capital_base=float(1000000),frequency='MINUTE',stock_market='STOCK',
benchmark='000300.SH',plot=True
)