代码拉取完成,页面将自动刷新
同步操作将从 天勤量化(TqSdk)/tqsdk-python 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#!usr/bin/env python3
# -*- coding:utf-8 -*-
__author__ = 'mayanqiong'
from abc import abstractmethod
class TqRiskRule(object):
def __init__(self, api, account=None):
# 记录必要参数, 每个风控规则都需要继承这个基类
self._api = api
account = self._api._account._check_valid(account)
if account is None:
raise Exception(f"多账户模式下, 需要指定账户实例 account")
self._account = account
self._account_key = self._account._account_key
@abstractmethod
def _could_insert_order(self, pack) -> (bool, str): # 是否可以下单
pass
@abstractmethod
def _on_insert_order(self, pack):
pass
@abstractmethod
def _on_settle(self):
pass
class TqRuleOpenCountsLimit(TqRiskRule):
"""
风控规则类 - 交易日内开仓次数限制。
此功能为 TqSdk 专业版提供,如需使用此功能,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk_professional/>`_ 申请试用或购买
"""
def __init__(self, api, open_counts_limit, symbol, account=None):
"""
Args:
api (TqApi): TqApi 实例
open_volumes_limit (int): 交易日内开仓手数上限
symbol (str/list of str): 负责限制的合约代码或合约代码列表.
* str: 一个合约代码
* list of str: 合约代码列表
account (TqAccount/TqKq/TqSim): [可选] 指定发送下单指令的账户实例, 多账户模式下,该参数必须指定
Example1::
from tqsdk import TqApi
from tqsdk.risk_rule import TqRuleOpenCountsLimit
api = TqApi(auth=TqAuth("信易账户", "账户密码"))
rule = TqRuleOpenCountsLimit(api, open_counts_limit=10, symbol="DCE.m2112") # 创建风控规则实例
api.add_risk_rule(rule) # 添加风控规则
quote = api.get_quote("DCE.m2112")
try:
# 每次最新价变动,下一笔订单,直到超过开仓次数风控限制
while True:
api.wait_update()
if api.is_changing(quote, ['last_price']):
order = api.insert_order(symbol="DCE.m2112", direction="BUY", offset="OPEN", volume=1)
while order.status != "FINISHED":
api.wait_update()
except TqRiskRuleError as e:
print('!!!', e)
api.close()
"""
super(TqRuleOpenCountsLimit, self).__init__(api=api, account=account)
if open_counts_limit < 0:
raise Exception("参数 open_volumes_limit 必须大于 0 的数字")
self.open_counts_limit = open_counts_limit
self.symbol_list = [symbol] if isinstance(symbol, str) else symbol
self.data = {s: 0 for s in self.symbol_list}
for order_id, order in self._api._data.get('trade', {}).get(self._account_key, {}).get('orders', {}).items():
symbol = order["exchange_id"] + "." + order["instrument_id"]
if order["offset"] == "OPEN" and symbol in self.data:
self.data[symbol] += 1
def _could_insert_order(self, pack) -> {bool, str}:
if pack['account_key'] == self._account_key:
symbol = pack["exchange_id"] + "." + pack["instrument_id"]
if pack["offset"] == "OPEN" and symbol in self.symbol_list:
if self.data[symbol] + 1 > self.open_counts_limit:
return False, f"触发风控规则,合约 {symbol} 开仓到达交易日内开仓次数限制 {self.open_counts_limit}, " \
f"已下单次数 {self.data[symbol]}"
return True, ""
def _on_insert_order(self, pack):
if pack['account_key'] == self._account_key:
symbol = pack["exchange_id"] + "." + pack["instrument_id"]
if pack["offset"] == "OPEN" and symbol in self.symbol_list:
self.data[symbol] += 1
def _on_settle(self):
for k in self.data.keys():
self.data[k] = 0
class TqRuleOpenVolumesLimit(TqRiskRule):
"""
风控规则类 - 交易日内开仓手数限制
此功能为 TqSdk 专业版提供,如需使用此功能,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk_professional/>`_ 申请试用或购买
"""
def __init__(self, api, open_volumes_limit, symbol, account=None):
"""
Args:
api (TqApi): TqApi 实例
open_volumes_limit (int): 交易日内开仓手数上限
symbol (str/list of str): 负责限制的合约代码或合约代码列表.
* str: 一个合约代码
* list of str: 合约代码列表
account (TqAccount/TqKq/TqSim): [可选] 指定发送下单指令的账户实例, 多账户模式下,该参数必须指定
Example1::
from tqsdk import TqApi
from tqsdk.risk_rule import TqRuleOpenVolumesLimit
api = TqApi(auth=TqAuth("信易账户", "账户密码"))
rule = TqRuleOpenVolumesLimit(api, open_volumes_limit=10, symbol="DCE.m2112") # 创建风控规则实例
api.add_risk_rule(rule) # 添加风控规则
# 下单 5 手,不会触发风控规则
order1 = api.insert_order(symbol="DCE.m2112", direction="BUY", offset="OPEN", volume=5)
while order1.status != "FINISHED":
api.wait_update()
# 继续下单 8 手,会触发风控规则
order2 = api.insert_order(symbol="DCE.m2112", direction="BUY", offset="OPEN", volume=8)
while order2.status != "FINISHED":
api.wait_update()
api.close()
Example2::
from tqsdk import TqApi, TqKq, TqRiskRuleError
from tqsdk.risk_rule import TqRuleOpenVolumesLimit
account = TqKq()
api = TqApi(account=account, auth=TqAuth("信易账户", "账户密码"))
rule = TqRuleOpenVolumesLimit(api, open_volumes_limit=10, symbol="DCE.m2112", account=account) # 创建风控规则实例
api.add_risk_rule(rule) # 添加风控规则
try:
# 下单 11 手,触发风控规则
order1 = api.insert_order(symbol="DCE.m2112", direction="BUY", offset="OPEN", volume=11)
while order1.status != "FINISHED":
api.wait_update()
except TqRiskRuleError as e:
print("!!!", e)
api.close()
"""
super(TqRuleOpenVolumesLimit, self).__init__(api=api, account=account)
if open_volumes_limit < 0:
raise Exception("参数 open_volumes_limit 必须大于 0 的数字")
self.open_volumes_limit = open_volumes_limit
self.symbol_list = [symbol] if isinstance(symbol, str) else symbol
self.data = {s: 0 for s in self.symbol_list}
for trade_id, trade in self._api._data.get('trade', {}).get(self._account_key, {}).get('trades', {}).items():
symbol = trade["exchange_id"] + "." + trade["instrument_id"]
if trade["offset"] == "OPEN" and symbol in self.data:
self.data[symbol] += trade["volume"]
def _could_insert_order(self, pack) -> {bool, str}:
if pack['account_key'] == self._account_key:
symbol = pack["exchange_id"] + "." + pack["instrument_id"]
if pack["offset"] == "OPEN" and symbol in self.symbol_list:
if self.data[symbol] + pack["volume"] > self.open_volumes_limit:
return False, f"触发风控规则,合约 {symbol} 开仓到达交易日内开仓手数限制 {self.open_volumes_limit}, " \
f"已下单手数 {self.data[symbol]}, 即将下单手数 {pack['volume']}"
return True, ""
def _on_insert_order(self, pack):
if pack['account_key'] == self._account_key:
symbol = pack["exchange_id"] + "." + pack["instrument_id"]
if pack["offset"] == "OPEN" and symbol in self.symbol_list:
self.data[symbol] += pack["volume"]
def _on_settle(self):
for k in self.data.keys():
self.data[k] = 0
class TqRuleAccOpenVolumesLimit(TqRiskRule):
"""
风控规则类 - 累计开仓手数限制。
限制合约开仓手数之和。
此功能为 TqSdk 专业版提供,如需使用此功能,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk_professional/>`_ 申请试用或购买
"""
def __init__(self, api, open_volumes_limit, symbol, account=None):
"""
Args:
api (TqApi): TqApi 实例
open_volumes_limit (int): 交易日内开仓手数之和上限
symbol (str/list of str): 负责限制的合约代码或合约代码列表.
* str: 一个合约代码
* list of str: 合约代码列表
account (TqAccount/TqKq/TqSim): [可选] 指定发送下单指令的账户实例, 多账户模式下,该参数必须指定
Example::
from tqsdk import TqApi, TqKq, TqRiskRuleError
from tqsdk.risk_rule import TqRuleAccOpenVolumesLimit
account = TqKq()
api = TqApi(account=account, auth=TqAuth("信易账户", "账户密码"))
quote = api.get_quote("SSE.000300")
call_in, call_at, call_out = api.query_all_level_finance_options("SSE.000300", quote.last_price, "CALL", nearbys=0)
put_in, put_at, put_out = api.query_all_level_finance_options("SSE.000300", quote.last_price, "PUT", nearbys=0)
near_symbols = call_in + call_at + call_out + put_in + put_at + put_out # 找到所有当月期权合约
symbols = api.query_options("SSE.000300", expired=False) # 找到所有中金所期权合约
# 规则1: 中金所当月期权合约日内开仓不超过 100 手
# 规则2: 中金所所有期权合约日内合约开仓不超过 200 手
rule1 = TqRuleAccOpenVolumesLimit(api, open_volumes_limit=100, symbol=near_symbols, account=account) # 创建风控规则实例
rule2 = TqRuleAccOpenVolumesLimit(api, open_volumes_limit=200, symbol=symbols, account=account) # 创建风控规则实例
api.add_risk_rule(rule1) # 添加风控规则
api.add_risk_rule(rule2) # 添加风控规则
try:
# 下单 101 手,触发风控规则
order1 = api.insert_order(symbol="CFFEX.IO2111-C-4900", direction="BUY", offset="OPEN", volume=101, limit_price=35.6)
while order1.status != "FINISHED":
api.wait_update()
except TqRiskRuleError as e:
print("!!!", e) # 报错,当月期权合约日内合约开仓不超过 100 手, 已下单次数 0
api.close()
"""
super(TqRuleAccOpenVolumesLimit, self).__init__(api=api, account=account)
if open_volumes_limit < 0:
raise Exception("参数 open_volumes_limit 必须大于 0 的数字")
self.open_volumes_limit = open_volumes_limit
self.open_volumes = 0 # 所有合约日内合约开仓手数
self.symbol_list = [symbol] if isinstance(symbol, str) else symbol
for trade_id, trade in self._api._data.get('trade', {}).get(self._account_key, {}).get('trades', {}).items():
if trade["offset"] == "OPEN" and f'{trade["exchange_id"]}.{trade["instrument_id"]}' in self.symbol_list:
self.open_volumes += trade['volume']
def _could_insert_order(self, pack) -> {bool, str}:
symbol = pack["exchange_id"] + "." + pack["instrument_id"]
if pack['account_key'] == self._account_key and symbol in self.symbol_list: # 当前账户下单
if pack["offset"] == "OPEN" and self.open_volumes + pack['volume'] > self.open_volumes_limit:
return False, f"触发风控规则,所有合约日内合约开仓不超过 {self.open_volumes_limit} 手, 已下单手数 {self.open_volumes}"
return True, ""
def _on_insert_order(self, pack):
symbol = pack["exchange_id"] + "." + pack["instrument_id"]
if pack['account_key'] == self._account_key and symbol in self.symbol_list: # 当前账户下单
if pack["offset"] == "OPEN": # 开仓单把手数累加
self.open_volumes += pack['volume']
def _on_settle(self):
self.open_volumes = 0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。