同花顺Python策略编辑器帮助文档

同花顺Python策略编辑器帮助文档


如何使用系统提供的信号功能进行策略监控

<h4><strong>1.什么是信号?</strong></h4> <p>信号是最常用的一些预警条件,为了让您可以直接订阅信号,而不用自己订阅行情、自己处理,我们实现了信号策略。通过信号的方式,大部分常见的策略可以从写一整个程序简化为写一句或几句信号语句,并达到相同的策略监控目的。</p> <h4><strong>2.信号策略怎么使用?</strong></h4> <pre><code>使用前请熟悉:策略编辑器目录下帮助/HQ接口.py,熟悉行情数据的字段定义,比如get_quote、get_kline的样例 使用前请熟悉:策略编辑器目录下帮助/xiadan接口.py, 熟悉其中cmd函数 使用样例参照:策略编辑器目录下信号策略/my_signals.py或下方的示例代码,也可以在my_signals.py目录新建自己的信号策略.py,运行自己的信号策略</code></pre> <p>信号策略主要涉及的函数包括:运行信号函数:run、删除信号函数:delete、暂停信号函数:pause、恢复信号函数:resume</p> <h5>(1)运行信号函数</h5> <p><strong>调用格式</strong></p> <pre><code>run(codelist, condition, action, predefine=None, period=None, lenth=None, interval=None) ''' @brief 运行信号策略函数。 @param codelist: 支持str of list,str,用于注册实时或历史数据,包含的关键字有: 纯数字:用户自定义代码列表(包括1A0001) position:持仓表 order:可撤委托表 fullorder:全量委托表 自选股:自选股列表 其他问句:先取自定义板块,取不到则问财选股 @param condition: str,相当于判断引号内的条件是否满足,满足则执行action内的行为;不满足则继续保持监控。包含的关键字有: quote:监控代码的分时(codelist中可填的多个股票代码都属于监控代码,而非辅助代码。codelist中包含多个股票代码时,分别判断它们每一个是否满足condition中的条件) quote2:辅助代码的分时 kline:监控代码的K线,采用kline[code][period][lenth]方式可以指定周期和条数,否则默认取30条日线,也可以通过set_kline_param设置默认周期和条数。 kline2:辅助代码的K线 code:本函数的第一个参数:codelist中行情数据更新的某个代码 @param action: str,信号触发后需执行的行为 @param predefine(可选参数): 支持str of list,str,数据项定义语句,信号触发前执行 @param period(可选参数): int,用户设置的历史数据的周期 @param lenth(可选参数): int,用户设置的历史数据的条数 @param interval(可选参数): int,用户设置的定时信号周期 @return: 策略ID '''</code></pre> <p>接下来举例说明监控代码的使用方式。例1中,监控标的‘600000’, 还可以替换为例如: ‘600000,000001’、‘order’、‘macd底背离前10个股票’等形式。</p> <p><strong>示例代码</strong></p> <pre><code>#例1:当600000的股票价格大于11.5元时,以最新价买入该股100股。 run('600000', "quote[code]['price'] &gt; 11.50", "xd.cmd('buy %s %s 100' % (code, 'zxjg'))") </code></pre> <p><strong>运行结果</strong></p> <p>运行信号后部分日志如下,可见,当600000股价到11.52元时,条件满足并触发,执行委托。</p> <pre><code>tips=send buy code:600000 price:11.52 amount:100 [28944][403280432][20191128_00000001]600000 已触发条件 [28944][403280432][20191128_00000001] 信号执行结束 tips=您的买入委托已成功提交,合同编号:1283470590。 </code></pre> <p>接下来举例说明辅助代码的使用方式:</p> <p><strong>示例代码</strong></p> <pre><code>#例2:当监控代码:000001的股票当日涨幅超过2%,且辅助代码:上证指数涨幅超过1%时,以最新价买入该股100股。 run('000001', "quote[code]['zf'] &gt; 0.02 and quote2['1A0001']['zf'] &gt; 0.01", "xd.cmd('buy {0} {1} 100'.format(code, quote[code]['price']))")</code></pre> <h5>(2)删除、暂停、恢复信号函数:</h5> <p>Python脚本运行run函数时,会将其放在另一个线程运行,然后执行Python脚本中后续的语句。因此例1、例2所有信号均直至条件触发后,才结束监控。手动点击停止脚本时,信号不会结束。如要在条件触发前终止信号监控,可以在程序中采用delete函数,如例3,或点击策略列表的删除、暂停、恢复按钮。</p> <p><strong>调用格式</strong></p> <pre><code>delete(signal_id) ''' @brief 删除信号函数 @param signal_id:run接口返回的策略ID @return 无 ''' pause(signal_id) ''' @brief 暂停信号运行函数 @param signal_id:run接口返回的策略ID @return 无 ''' resume(signal_id) ''' @brief 恢复信号运行函数 @param signal_id:run接口返回的策略ID @return 无 '''</code></pre> <p><strong>示例代码</strong></p> <pre><code>#例3:系统内置的时间信号(该信号调用方式可见本节第3点:已内置哪些信号):信号运行后,每5s检查一次,当日时间超过15:32分时,按最新价买入600000 100股,当脚本运行约60s后,删除信号,终止监控。 import time localtime1 = time.localtime(time.time()) print("运行run语句前时刻 :", localtime1) id = run('600000', "f_sj(161000)", "xd.cmd('buy {0} zxjg 100'.format(code))", interval=5) localtime2 = time.localtime(time.time()) print("运行run语句后时刻 :", localtime2) time.sleep(60) delete(id)</code></pre> <p><strong>运行结果</strong></p> <pre><code>运行run语句前时刻 : time.struct_time(tm_year=2019, tm_mon=11, tm_mday=19, tm_hour=16, tm_min=9, tm_sec=9, tm_wday=1, tm_yday=323, tm_isdst=0) 运行run语句后时刻 : time.struct_time(tm_year=2019, tm_mon=11, tm_mday=19, tm_hour=16, tm_min=9, tm_sec=9, tm_wday=1, tm_yday=323, tm_isdst=0) [27428][384506928][20191119_00000007]600000 未达到触发条件 [27428][384506928][20191119_00000007]600000 未达到触发条件 [27428][384506928][20191119_00000007]600000 未达到触发条件 tips=send buy code:600000 price:12.23 amount:100 [27428][384506928][20191119_00000007]600000 已触发条件 [27428][384506928][20191119_00000007] 信号执行结束 tips=您的买入委托已成功提交,合同编号:1273104514。 [16600][384506928][20191119_00000007] 设置信号状态为删除</code></pre> <p>由于Python脚本运行run函数时,会将其放在另一个线程运行,然后执行Python脚本中后续的语句。因此,运行run语句后时刻和运行run语句前时刻几乎相同,信号监测和run函数后的sleep等程序运行互不影响。之后信号达到时间条件后触发,执行委托。</p> <h4><strong>3.已内置哪些信号?</strong></h4> <p><strong>调用格式</strong></p> <pre><code>f_cghl(quote, code, P, R) ''' @brief 冲高P元回落R% (最高价高于P,当前价格再比最高价回落R%) @param quote: 实时行情数据 @param code: 指定代码 @param P: 冲高比较价格 @param R: 回落比较比例 @return: True code满足冲高P元回落R%的条件 False code不满足冲高P元回落R%的条件 ''' f_dkztb(quote, code, wtje) ''' @brief 打开涨停板:当封板的金额小于设定的阀值时触发 @param quote: 实时行情数据 @param code: 指定代码 @param wtje: 封板金额阈值 @return: True or False ''' f_fzt(quote, code, up_b1_je = None, down_b1_je = None) ''' @brief 封涨停,排除持续涨停的情况,涨停后在判断封单金额的上下限 @param quote: 实时行情数据 @param code: 指定代码 @param up_b1_je: 封单金额上限 @param down_b1_je: 封单金额下限 @return: True or False ''' f_sj(T) ''' @brief 时间信号,系统时间&gt;=T触发 @param T: int,比如9:30,T应该设置为093000 @return: True or False ''' f_fthlfd(quote, code, threshold, time_second) ''' @brief 反弹回落幅度:持续监控最近time_second的时间段内,股票的反弹回落幅度(当前的最新价和时间段内的最低价、最高价比较),若该幅度超过设定阈值则触发相应操作(一般是委托) @param quote: 实时行情数据 @param code: 指定代码 @param threshold: 涨跌幅阈值,跌为负,涨为正;跌幅小于负的阈值或涨幅大于正的阈值,条件触发;阈值不为百分数,是实际值,如上涨2%为0.02 @param time_second: 监控的时间段长度,单位:秒; 可输入范围:0到24*60*60 @return: True or False ''' f_MACD(api, code, period_macd, form_macd, form_macd_count, period_inspect=100) ''' @brief MACD条件: (1)一次金叉/死叉:当程序启动后,出现新的金叉/死叉,条件触发,执行设置的委托。 (2)二次金叉/死叉:设置某个时间长度,持续监控最近期的该时间窗口,当程序启动后,出现新的金叉/死叉,且在窗口中以前出现过至少一次金叉/死叉时,条件触发,执行设置的委托。 (3)底背离/顶背离:设置某个时间长度,持续监控最近期的该时间窗口,当程序启动后,股价出现新低/新高(该新低/新高比窗口中的低点/高点更低/更高),但此时DIF未创新低/新高,条件触发,执行设置的委托。 @param api: 导入hq.ths_hq_api,用于修改kline的周期 @param code: 指定代码 @param period_macd: 取哪个周期的MACD作为条件 @param form_macd: 'j'金叉/底背离;'s'死叉/顶背离 @param form_macd_count: 1,2=&gt;1次,2次(金叉或死叉);3=&gt;顶或底背离。配合form_macd,例如form_macd='j',form_macd_count=3,表示底背离。 @param period_inspect=100: 监控的时间窗口长度 @return: True or False '''</code></pre> <p><strong>示例代码</strong></p> <pre><code>#例4:持仓股中有股票出现涨停,后封板金额小于阈值100万元,不弹窗确认委托,直接自动清仓该股票。 run('position', "f_dkztb(quote, code, 1000000)", "xd.cmd('sell {0} {1} -cw 1/1 -notip'.format(code, quote[code]['price']))") </code></pre> <h4><strong>4.如何添加自定义信号?</strong></h4> <p>如果内置的信号策略不满足您的需求,您可以按如下方式添加自定义信号。</p> <pre><code>打开xiadan.exe同目录的script\信号策略\my_defines.py 仿照内置的信号添加自定义信号,改完后执行或者退出下单进程并重新启动 写函数前需要了解的已有的定义: api:ths_hq_api的实例 quote:实时数据 quote2:辅助代码实时数据 kline:周期数据 kline2:辅助周期数据 code:当前更新数据的代码 上述6个变量可以直接在函数内使用,而无需定义。需要使用上述变量的时候,以传参形式传给自定义函数。</code></pre> <h4><strong>5.如何预定义、预处理数据?</strong></h4> <p><strong>示例代码</strong></p> <pre><code>#!/usr/bin/env python # -*- coding: utf-8 -*- #例5:当持仓股中,某股票换手率大于0.5%且亏损5%,或某股票盈利5%,卖出该股票仓位的1/3进行止损或止盈,并继续监控其它还未达到触发条件的持仓股。 from ths_api import * pre=[ "price = quote[code]['price']", "hs = quote[code]['hs']", "cbj = xd.g_position[code]['cbj']" ] condition = "hs &gt; 0.005 and price &gt; cbj*(1+{0}) or price &lt; cbj*(1-{1})".format(0.05, 0.05) action = "xd.cmd('sell {0} {1} -cw 1/3'.format(code, 'dsj1'))" id = run('position', condition, action, predefine=pre) print('信号已提交,ID=', id)</code></pre> <p>上例中,将预定义的变量放在pre的列表中,之后写多个条件的信号时,可以直接采用简写的预定义变量名,如:price、hs等,从而简化信号程序。</p> <p>如果信号的触发条件带有多个条件的逻辑关系,如上例,则如果监控标的是指定代码形式(code=‘000001’这种方式),那么每个信号程序的监控标的只能为一个股票代码,而不能是多个股票代码(str of list形式)。但如果是position,可以支持多个持仓股同时监控。</p> <h4><strong>6.如何使用周期行情数据?</strong></h4> <p><strong>调用格式</strong></p> <pre><code>目前支持3种格式 (1)kline[code][period][lenth][第几行数据][具体数据项]:可以解析出指定的period、lenth (2)kline[code][第几行数据][具体数据项]:默认30条日线数据 (3)api.MA(kline, code, 5):默认取30条日线数据计算均线 如用(2)、(3)格式,也可以通过设置run函数的period、lenth参数,将周期行情数据的周期和条数默认值改变为所需数值。 run(codelist, condition, action, predefine=None, period=None, lenth=None, interval=None),函数的调用方式可见本节第二点:信号策略怎么使用。</code></pre> <p><strong>示例代码</strong></p> <pre><code>#例6:当最新的一分钟K线的最高价大于12.45时,以最新价买入600000 100股 run('600000', "kline[code][-1]['high'] &gt; 12.45", "xd.cmd('buy {0} {1} 100'.format(code, quote[code]['price']))", period=1, lenth=60) </code></pre> <h4><strong>7.如何调整信号触发条件的默认检测时间间隔?</strong></h4> <p>当触发条件不是通过行情数据进行判断时,例如定时信号的触发完全不需要行情数据,系统会默认每3s的时间间隔后判断一次该类条件。如果用户觉得默认检测的时间间隔需要调整,可以通过run函数的interval参数指定所需的时间间隔,函数的调用方式可见本节第二点:信号策略怎么使用。</p> <p><strong>调用格式</strong></p> <pre><code>run(codelist, condition, action, predefine=None, period=None, lenth=None, interval=None)</code></pre> <p><strong>示例代码</strong></p> <pre><code>#例7:当时间达到或超过当日14:00时,以最新价买600000 100股。并设置检测时间间隔为5,即5s判断一次条件(需要注意的一点是,条件触发后的动作里面也不要有行情相关的数据) run('600000', "f_sj(140000)", "xd.cmd('buy {0} zxjg 100'.format(code))", interval=5) </code></pre>

页面列表

ITEM_HTML