Ejemplo n.º 1
0
class TqsdkClient(LocalClient):
    def __init__(self, **kwargs):
        super().__init__()
        self.p = Thread(target=self.init_api, args=())
        self.p.start()
        self.api = None

    def init_api(self):

        self.api = TqApi()
        while True:
            self.api.wait_update()

    def get(self, *argsm, **params):
        """ 调用他们的历史数据 """

        # tick数据
        if params.get("level") == "tick":
            del params['level']
            temp = self.api.get_tick_serial(*argsm, **params)
            return temp

        # 分钟线数据
        if params.get("level") != "tick":
            return self.api.get_kline_serial(*argsm, **params)

    def set(self):
        pass
Ejemplo n.º 2
0
    def test_get_kline_serial(self):
        """
        获取K线数据
        """
        # 预设服务器端响应
        self.mock.run("test_md_basic_get_kline_serial.script")

        # 测试: 获取K线数据
        TqApi.RD = random.Random(1)
        api = TqApi(_ins_url=self.ins_url,
                    _td_url=self.td_url,
                    _md_url=self.md_url)
        klines = api.get_kline_serial("SHFE.cu1909", 10)
        self.assertEqual(klines.iloc[-1].close, 47580.0)
        self.assertEqual(klines.iloc[-1].id, 660788)
        self.assertEqual(klines.iloc[-2].id, 660787)
        self.assertEqual(klines.iloc[-1].datetime, 1.56861719e+18)
        self.assertEqual(klines.iloc[-1].open, 47580)
        self.assertEqual(klines.iloc[-1].volume, 0.0)
        self.assertEqual(klines.iloc[-1].open_oi, 6940.0)
        self.assertEqual(klines.iloc[-1].duration, 10)
        # 其他取值方式
        self.assertEqual(klines.duration.iloc[-1], 10)
        self.assertEqual(klines.iloc[-1]["duration"], 10)
        self.assertEqual(klines["duration"].iloc[-1], 10)
        # 报错测试
        self.assertRaises(Exception, api.get_kline_serial, "SHFE.au1999", 10)
        self.assertRaises(AttributeError, klines.iloc[-1].__getattribute__,
                          "dur")
        self.assertRaises(KeyError, klines.iloc[-1].__getitem__, "dur")
        api.close()
Ejemplo n.º 3
0
    def test_get_kline_serial(self):
        """
        获取K线数据
        """
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(
            os.path.join(dir_path, "log_file",
                         "test_md_basic_get_kline_serial.script.lzma"))

        # 测试: 获取K线数据
        utils.RD = random.Random(1)
        api = TqApi(_ins_url=self.ins_url_2019_07_03,
                    _td_url=self.td_url,
                    _md_url=self.md_url)
        klines = api.get_kline_serial("SHFE.cu1909", 10)
        self.assertEqual(klines.iloc[-1].close, 47580.0)
        self.assertEqual(klines.iloc[-1].id, 660788)
        self.assertEqual(klines.iloc[-2].id, 660787)
        self.assertEqual(klines.iloc[-1].datetime, 1.56861719e+18)
        self.assertEqual(klines.iloc[-1].open, 47580)
        self.assertEqual(klines.iloc[-1].volume, 0.0)
        self.assertEqual(klines.iloc[-1].open_oi, 6940.0)
        self.assertEqual(klines.iloc[-1].duration, 10)
        # 其他取值方式
        self.assertEqual(klines.duration.iloc[-1], 10)
        self.assertEqual(klines.iloc[-1]["duration"], 10)
        self.assertEqual(klines["duration"].iloc[-1], 10)
        # 报错测试
        self.assertRaises(Exception, api.get_kline_serial, "SHFE.au1999", 10)
        self.assertRaises(AttributeError, klines.iloc[-1].__getattribute__,
                          "dur")
        self.assertRaises(KeyError, klines.iloc[-1].__getitem__, "dur")
        api.close()
Ejemplo n.º 4
0
def sync_db():
    api = TqApi()
    queryset = DatabaseSqlite()

    for item in sync_list:
        try:
            df = api.get_kline_serial(
                symbol=item["symbol_tq"],
                duration_seconds=item.get(
                    "duration_seconds", default_settings["duration_seconds"]),
                data_length=item.get("data_length",
                                     default_settings["data_length"]))
            queryset.update_from_df(df=df,
                                    exchange=item["exchange"],
                                    symbol=item["symbol_db"],
                                    interval=item.get(
                                        "interval",
                                        default_settings["interval"]),
                                    time_handler_type="nanometre")
        except Exception as error:
            print(f"{item['symbol_tq']} 同步失败,原因:{error}")

    queryset.close()

    print("\n列表同步完毕!!!")
Ejemplo n.º 5
0
def run_tianqin_code(port):
    try:
        api = TqApi(web_gui="127.0.0.1:" + port)
        klines = api.get_kline_serial("SHFE.au1910", 24 * 60 * 60)
        ma = MA(klines, 30)  # 使用tqsdk自带指标函数计算均线
        while True:
            api.wait_update()
    except Exception as e:
        api.close()
Ejemplo n.º 6
0
def run_tianqin_code(port, queue):
    try:
        ins_url = "http://127.0.0.1:5000/t/md/symbols/2019-07-03.json"
        api = TqApi(_ins_url=ins_url, web_gui="127.0.0.1:" + port)
        queue.put("webready")
        klines = api.get_kline_serial("SHFE.au1910", 24 * 60 * 60)
        ma = MA(klines, 30)  # 使用tqsdk自带指标函数计算均线
        while True:
            api.wait_update()
    except Exception as e:
        api.close()
Ejemplo n.º 7
0
class TqSdkClient(LocalClient):
    def __init__(self, **kwargs):
        self.api = TqApi()

    def get(self, **params):
        """ 调用他们的历史数据 """
        if params.get("level") == "tick":
            return self.api.get_tick_serial(*self._parse_params(params))
        if params.get("level") != "tick":
            return self.api.get_kline_serial(*self._parse_params(params))

    def _parse_params(self, params):
        """
        将参数解析为tq可以理解的方式
        都需要返回一个*args
        """
        level = params.get("level")
        local_symbol = params.get("local_symbol")
        length = params.get("length")
        if level != "tick":
            return [local_symbol, self.get_seconds(level), length]
        return [local_symbol, length]

    @staticmethod
    def get_seconds(level) -> int:
        """
        将level转换到秒
        * level: 数据等级
        """
        min_r = r"(\d{1,2})min"
        hour_r = r"(\d{1,2})h"
        day_r = r"(\d{1,2})day"
        if "min" in level:
            try:
                return int(re.match(min_r, level).group(1)) * 60
            except Exception:
                raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1min这样的格式")
        if "h" in level:
            try:
                return int(re.match(hour_r, level).group(1)) * 3600
            except Exception:
                raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1min这样的格式")
        if "day" in level:
            try:
                return int(re.match(day_r, level).group(1)) * 3600 * 24
            except Exception:
                raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1day这样的格式")
Ejemplo n.º 8
0
    def test_wait_update_1(self):
        """
        若未连接天勤时修改了K线字段,则不应发送set_chart_data指令到服务器 (即不能调用api.py中_process_serial_extra_array()); 否则导致与服务器断连
        related issue: #146
        """
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(os.path.join(dir_path, "log_file", "test_func_wait_update_1.script"))
        # 测试
        api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url)
        TqApi.RD = random.Random(4)
        klines = api.get_kline_serial("SHFE.cu1911", 10)
        klines["ma"] = MA(klines, 15)  # 测试语句
        deadline = time.time() + 10
        while api.wait_update(deadline=deadline):
            pass

        api.close()
Ejemplo n.º 9
0
def run_tianqin_code(port):
    try:
        api = TqApi(backtest=TqBacktest(start_dt=date(2018, 5, 5),
                                        end_dt=date(2018, 5, 10)),
                    web_gui="127.0.0.1:" + port)
        klines = api.get_kline_serial("DCE.m1901", 5 * 60, data_length=15)
        target_pos = TargetPosTask(api, "DCE.m1901")
        while True:
            api.wait_update()
            if api.is_changing(klines):
                ma = sum(klines.close.iloc[-15:]) / 15
                if klines.close.iloc[-1] > ma:
                    target_pos.set_target_volume(5)
                elif klines.close.iloc[-1] < ma:
                    target_pos.set_target_volume(0)
    except BacktestFinished as e:
        while True:
            api.wait_update()
    except Exception as e:
        api.close()
Ejemplo n.º 10
0
def main(argv=None):
    """
    测试脚本内容
    """
    if argv is None:
        argv = sys.argv
    # acc = TqAccount("快期模拟", config_se['simAccoutName'], \
    #     config_se['simAccoutName'])
    acc = TqSim()
    api = TqApi(acc)

    # try:
    # 执行策略方法
    kline = api.get_kline_serial("SHFE.cu1903", 7 * 24 * 60 * 60)
    for i in range(200):
        kline.iloc[i,
                   0] = datetime.fromtimestamp(kline.iloc[i, 0] / 1000000000)

    print(kline.iloc[-20:-1, :])
    # Strategy(api, "xxx").aberration()
    api.close()
Ejemplo n.º 11
0
        def backtest():
            """
            回测耗时测试
            """
            # 预设服务器端响应
            dir_path = os.path.dirname(os.path.realpath(__file__))
            log_path = os.path.join(dir_path, "log_file",
                                    "test_backtest.script.lzma")
            times = []
            for i in range(20):
                mock = MockServer()
                md_url = "ws://127.0.0.1:5100/"
                td_url = "ws://127.0.0.1:5200/"
                mock.run(log_path)
                utils.RD = random.Random(4)
                try:
                    start = datetime.datetime.now()
                    backtest = TqBacktest(
                        start_dt=datetime.datetime(2019, 8, 10),
                        end_dt=datetime.datetime(2019, 9, 11))
                    api = TqApi(backtest=backtest,
                                _ins_url=self.ins_url_2019_07_03,
                                _md_url=md_url,
                                _td_url=td_url)
                    symbol = "DCE.m2005"
                    klines = api.get_kline_serial(symbol, duration_seconds=60)
                    while True:
                        api.wait_update()
                except BacktestFinished:
                    delta = datetime.datetime.now() - start
                    self.assertLess(delta.seconds, 60)
                    times.append(delta.seconds + delta.microseconds * 1e-6)
                    # print(delta.seconds + delta.microseconds * 1e-6)
                    api.close()
                    mock.close()

            print(times)
            print(sum(times))
Ejemplo n.º 12
0
def run_tianqin_code(port, queue):
    try:
        ins_url = "http://127.0.0.1:5000/t/md/symbols/2019-07-03.json"
        api = TqApi(backtest=TqBacktest(start_dt=date(2019, 7, 10),
                                        end_dt=date(2019, 7, 20)),
                    _ins_url=ins_url,
                    web_gui="127.0.0.1:" + port)
        queue.put("webready")
        klines = api.get_kline_serial("DCE.m1912", 5 * 60, data_length=15)
        target_pos = TargetPosTask(api, "DCE.m1912")
        while True:
            api.wait_update()
            if api.is_changing(klines):
                ma = sum(klines.close.iloc[-15:]) / 15
                if klines.close.iloc[-1] > ma:
                    target_pos.set_target_volume(5)
                elif klines.close.iloc[-1] < ma:
                    target_pos.set_target_volume(0)
    except BacktestFinished as e:
        while True:
            api.wait_update()
    except Exception as e:
        api.close()
Ejemplo n.º 13
0
fh.setLevel(logging.DEBUG)  # 输出到file的log等级的开关
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)  # 输出到console的log等级的开关
# 第三步,定义handler的输出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 第四步,将logger添加到handler里面
logger.addHandler(fh)
logger.addHandler(ch)

api = TqApi(TqSim())

#time_slot_start = datetime.time(START_HOUR, START_MINUTE)  # 计划交易时段起始时间点
#time_slot_end = datetime.time(END_HOUR, END_MINUTE)  # 计划交易时段终点时间点
klines = api.get_kline_serial(SYMBOL, TIME_CELL, data_length=int(10 * 60 * 60 / TIME_CELL))
target_pos = TargetPosTask(api, SYMBOL)
position = api.get_position(SYMBOL)  # 持仓信息
quote = api.get_quote(SYMBOL)

logger.info("start %s daily strategy for %s!"%(c, SYMBOL))

current_volume = 0  # 记录持仓量
traded_volume = 0
cur_trading_date = ''

# 交易预警参数
k_count = 0
signal_interval = 10

short_price = 0.0
Ejemplo n.º 14
0
from tqsdk import TqApi, TqSim, TargetPosTask,TqAccount,TqBacktest
from tqsdk.ta import MA,SMA,SAR
from datetime import date
from tqsdk import TqReplay
from tqsdk.tafunc import ma
data_length = 200  # k线数据长度

SYMBOL = "SHFE.rb2005"  # 合约代码
api = TqApi(TqAccount("simnow", "090828", "jimc1230",front_broker='9999',front_url='tcp://180.168.146.187:10100'),web_gui="0.0.0.0:9876")#web_gui="0.0.0.0:9876"
# api = TqApi(backtest=TqBacktest(start_dt=date(2020, 3,10), end_dt=date(2020, 3, 19)),web_gui="0.0.0.0:9876")#"0.0.0.0:9876"#回测模式
# api = TqApi(backtest = TqReplay(date(2020,3,18)),web_gui="0.0.0.0:9876")#复盘模式
print("策略开始运行")


# "duration_seconds=60"为一分钟线, 日线的duration_seconds参数为: 24*60*60
klines = api.get_kline_serial(SYMBOL, duration_seconds=1*60, data_length=data_length)

#收盘后不可查
target_pos = TargetPosTask(api, SYMBOL)
position = api.get_position(SYMBOL)#指定一个品种查看持仓相关信息
account = api.get_account()#获取用户账户资金信息

while True:
    api.wait_update()
    
    

    if api.is_changing(klines.iloc[-1], "datetime"):  # 产生新k线:重新计算SMA
        klines["ma5"]=ma(klines["close"], 5) 
        klines["ma10"]=ma(klines["close"], 10)  
        klines["ma89"]=ma(klines["close"], 89)
Ejemplo n.º 15
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

import datetime
from tqsdk import TqApi, TqSim
from tqsdk.ta import *

api = TqApi(TqSim())
# 获得 cu1906 10秒K线的引用
klines = api.get_kline_serial("SHFE.cu1906", 10, data_length=3000)

print("K线时间",
      datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9))
print(klines)

print("ATR", ATR(klines, 26))
print("BIAS", BIAS(klines, 6))
print("BOLL", BOLL(klines, 3, 5))
print("DMI", DMI(klines, 14, 6))
print("KDJ", KDJ(klines, 9, 3, 3))
print("MA", MA(klines, 3))
print("MACD", MACD(klines, 20, 35, 10))
print("SAR", SAR(klines, 4, 0.02, 0.2))

api.close()
Ejemplo n.º 16
0
#!usr/bin/env python3
#-*- coding:utf-8 -*-
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from datetime import date
from tqsdk import TqApi, TqReplay, TargetPosTask
'''
复盘 2019-11-12
如果当前价格大于5分钟K线的MA15则开多仓,如果小于则平仓
'''
# 在创建 api 实例时传入 TqReplay 就会进入复盘模式, 同时打开 web_gui
api = TqApi(backtest=TqReplay(date(2019, 11, 12)), web_gui=True)
# 获得 m1901 5分钟K线的引用
klines = api.get_kline_serial("SHFE.cu2001", 5 * 60, data_length=15)
# 创建 m1901 的目标持仓 task,该 task 负责调整 m1901 的仓位到指定的目标仓位
target_pos = TargetPosTask(api, "SHFE.cu2001")

while True:
    api.wait_update()
    if api.is_changing(klines):
        ma = sum(klines.close.iloc[-15:]) / 15
        print("最新价", klines.close.iloc[-1], "MA", ma)
        if klines.close.iloc[-1] > ma:
            print("最新价大于MA: 目标多头5手")
            # 设置目标持仓为多头5手
            target_pos.set_target_volume(5)
        elif klines.close.iloc[-1] < ma:
            print("最新价小于MA: 目标空仓")
            # 设置目标持仓为空仓
Ejemplo n.º 17
0
#STEP1:交易信号汇总
trading_date = ''

parser = argparse.ArgumentParser()
parser.add_argument('--SYMBOL')
args = parser.parse_args()

if args.SYMBOL != None:
    SYMBOL = args.SYMBOL
else:
    SYMBOL = "DCE.i2005"

#STEP2:log
logger.info("Starting yiboduo strategy for: %s"%SYMBOL)
api = TqApi(TqSim())
klines = api.get_kline_serial(SYMBOL, duration_seconds=60*60*24, data_length=20)    
#ticks = api.get_tick_serial(SYMBOL)
quote = api.get_quote(SYMBOL)

while True:
    api.wait_update()

    # 跟踪log信息,日k数据会产生两个信号:一个是开盘时,另一个时收盘;如果想根据收盘k线分析前期趋势,用第二个信号
    # 这样就没有之前认为必须开盘才能分析之前所存在的趋势型机会了。
    # 实盘是只要14:59或盘后任何时间触发运行即可,一次退出;
    # 想尾盘参与策略型机会则收盘前运行回报策略型机会,次日择机参与则盘后任何时间运行即可
    if api.is_changing(klines):
        df = klines.to_dataframe()

        #logger.info("DATE: %s, close: %f"%(get_market_day(klines[-1]["datetime"]), klines[-1]["close"]))
        trading_date = bases.get_market_day(klines[-1]["datetime"])
Ejemplo n.º 18
0
from contextlib import closing

import numpy as np
import pandas as pd
from tqsdk import TqApi

from technical_indicators import SMA

# import seaborn as sns
# sns.set_style('white')

SYMBOL = 'CFFEX.IF1904'

api = TqApi('SIM')

klines = api.get_kline_serial(SYMBOL, duration_seconds=60)
quote = api.get_quote(SYMBOL)


def wave(klines, w=1, X=20):
    ys = pd.Series(data=klines.close[-100:-1],
                   index=[
                       str(dt.datetime.fromtimestamp(i / 1e9))
                       for i in klines.datetime[-100:-1]
                   ])
    l = len(ys)
    ls_ix = ys.index.tolist()
    ls_ix_peaks = []
    ls_ix_bottoms = []

    for i in range(l - w - 1, w - 1, -1):
Ejemplo n.º 19
0
__author__ = 'chengzhi'

from datetime import date
from contextlib import closing
from tqsdk import TqApi, TqSim, TqBacktest, TargetPosTask
'''
如果当前价格大于5分钟K线的MA15则开多仓
如果小于则平仓
回测从 2018-05-01 到 2018-10-01
'''
# 在创建 api 实例时传入 TqBacktest 就会进入回测模式
api = TqApi(TqSim(),
            backtest=TqBacktest(start_dt=date(2018, 5, 1),
                                end_dt=date(2018, 10, 1)))
# 获得 m1901 5分钟K线的引用
klines = api.get_kline_serial("DCE.m1901", 5 * 60, data_length=15)
# 创建 m1901 的目标持仓 task,该 task 负责调整 m1901 的仓位到指定的目标仓位
target_pos = TargetPosTask(api, "DCE.m1901")

# 使用with closing机制确保回测完成后释放对应的资源
with closing(api):
    while True:
        api.wait_update()
        if api.is_changing(klines):
            ma = sum(klines.close.iloc[-15:]) / 15
            print("最新价", klines.close.iloc[-1], "MA", ma)
            if klines.close.iloc[-1] > ma:
                print("最新价大于MA: 目标多头5手")
                # 设置目标持仓为多头5手
                target_pos.set_target_volume(5)
            elif klines.close.iloc[-1] < ma:
Ejemplo n.º 20
0
class Turtle:
    def __init__(self,
                 account,
                 symbol,
                 donchian_channel_open_position=20,
                 donchian_channel_stop_profit=10,
                 atr_day_length=20,
                 max_risk_ratio=0.5):
        self.account = account  # 交易账号
        self.symbol = symbol  # 合约代码
        self.donchian_channel_open_position = donchian_channel_open_position  # 唐奇安通道的天数周期(开仓)
        self.donchian_channel_stop_profit = donchian_channel_stop_profit  # 唐奇安通道的天数周期(止盈)
        self.atr_day_length = atr_day_length  # ATR计算所用天数
        self.max_risk_ratio = max_risk_ratio  # 最高风险度
        self.state = {
            "position": 0,  # 本策略净持仓数(正数表示多头,负数表示空头,0表示空仓)
            "last_price": float("nan"),  # 上次调仓价
        }

        self.n = 0  # 平均真实波幅(N值)
        self.unit = 0  # 买卖单位
        self.donchian_channel_high = 0  # 唐奇安通道上轨
        self.donchian_channel_low = 0  # 唐奇安通道下轨

        self.api = TqApi(self.account)
        self.quote = self.api.get_quote(self.symbol)
        # 由于ATR是路径依赖函数,因此使用更长的数据序列进行计算以便使其值稳定下来
        kline_length = max(donchian_channel_open_position + 1,
                           donchian_channel_stop_profit + 1,
                           atr_day_length * 5)
        self.klines = self.api.get_kline_serial(self.symbol,
                                                24 * 60 * 60,
                                                data_length=kline_length)
        self.account = self.api.get_account()
        self.target_pos = TargetPosTask(self.api,
                                        self.symbol,
                                        init_pos=self.state["position"])

    def recalc_paramter(self):
        # 平均真实波幅(N值)
        self.n = ATR(self.klines, self.atr_day_length)["atr"].iloc[-1]
        # 买卖单位
        self.unit = int((self.account.balance * 0.01) /
                        (self.quote.volume_multiple * self.n))
        # 唐奇安通道上轨:前N个交易日的最高价
        self.donchian_channel_high = max(
            self.klines.high[-self.donchian_channel_open_position - 1:-1])
        # 唐奇安通道下轨:前N个交易日的最低价
        self.donchian_channel_low = min(
            self.klines.low[-self.donchian_channel_open_position - 1:-1])
        print("唐其安通道上下轨: %f, %f" %
              (self.donchian_channel_high, self.donchian_channel_low))
        return True

    def set_position(self, pos):
        self.state["position"] = pos
        self.state["last_price"] = self.quote["last_price"]
        self.target_pos.set_target_volume(self.state["position"])

    def try_open(self):
        """开仓策略"""
        while self.state["position"] == 0:
            self.api.wait_update()
            if self.api.is_changing(self.klines.iloc[-1],
                                    "datetime"):  # 如果产生新k线,则重新计算唐奇安通道及买卖单位
                self.recalc_paramter()
            if self.api.is_changing(self.quote, "last_price"):
                print("最新价: %f" % self.quote.last_price)
                if self.quote.last_price > self.donchian_channel_high:  # 当前价>唐奇安通道上轨,买入1个Unit;(持多仓)
                    print("当前价>唐奇安通道上轨,买入1个Unit(持多仓): %d 手" % self.unit)
                    self.set_position(self.state["position"] + self.unit)
                elif self.quote.last_price < self.donchian_channel_low:  # 当前价<唐奇安通道下轨,卖出1个Unit;(持空仓)
                    print("当前价<唐奇安通道下轨,卖出1个Unit(持空仓): %d 手" % self.unit)
                    self.set_position(self.state["position"] - self.unit)

    def try_close(self):
        """交易策略"""
        while self.state["position"] != 0:
            self.api.wait_update()
            if self.api.is_changing(self.quote, "last_price"):
                print("最新价: ", self.quote.last_price)
                if self.state["position"] > 0:  # 持多单
                    # 加仓策略: 如果是多仓且行情最新价在上一次建仓(或者加仓)的基础上又上涨了0.5N,就再加一个Unit的多仓,并且风险度在设定范围内(以防爆仓)
                    if self.quote.last_price >= self.state[
                            "last_price"] + 0.5 * self.n and self.account.risk_ratio <= self.max_risk_ratio:
                        print("加仓:加1个Unit的多仓")
                        self.set_position(self.state["position"] + self.unit)
                    # 止损策略: 如果是多仓且行情最新价在上一次建仓(或者加仓)的基础上又下跌了2N,就卖出全部头寸止损
                    elif self.quote.last_price <= self.state[
                            "last_price"] - 2 * self.n:
                        print("止损:卖出全部头寸")
                        self.set_position(0)
                    # 止盈策略: 如果是多仓且行情最新价跌破了10日唐奇安通道的下轨,就清空所有头寸结束策略,离场
                    if self.quote.last_price <= min(
                            self.klines.
                            low[-self.donchian_channel_stop_profit - 1:-1]):
                        print("止盈:清空所有头寸结束策略,离场")
                        self.set_position(0)

                elif self.state["position"] < 0:  # 持空单
                    # 加仓策略: 如果是空仓且行情最新价在上一次建仓(或者加仓)的基础上又下跌了0.5N,就再加一个Unit的空仓,并且风险度在设定范围内(以防爆仓)
                    if self.quote.last_price <= self.state[
                            "last_price"] - 0.5 * self.n and self.account.risk_ratio <= self.max_risk_ratio:
                        print("加仓:加1个Unit的空仓")
                        self.set_position(self.state["position"] - self.unit)
                    # 止损策略: 如果是空仓且行情最新价在上一次建仓(或者加仓)的基础上又上涨了2N,就平仓止损
                    elif self.quote.last_price >= self.state[
                            "last_price"] + 2 * self.n:
                        print("止损:卖出全部头寸")
                        self.set_position(0)
                    # 止盈策略: 如果是空仓且行情最新价升破了10日唐奇安通道的上轨,就清空所有头寸结束策略,离场
                    if self.quote.last_price >= max(
                            self.klines.
                            high[-self.donchian_channel_stop_profit - 1:-1]):
                        print("止盈:清空所有头寸结束策略,离场")
                        self.set_position(0)

    def strategy(self):
        """海龟策略"""
        print("等待K线及账户数据...")
        deadline = time.time() + 5
        while not self.recalc_paramter():
            if not self.api.wait_update(deadline=deadline):
                raise Exception("获取数据失败,请确认行情连接正常并已经登录交易账户")
        while True:
            self.try_open()
            self.try_close()
Ejemplo n.º 21
0
Archivo: qq1.py Proyecto: bebeter/pyT
#!usr/bin/env python3
#-*- coding:utf-8 -*-

from tqsdk import TqApi, tafunc
from tqsdk.ta import *

api = TqApi()

underlying_quote = api.get_quote("CFFEX.IF2002")
klines = api.get_kline_serial('CFFEX.IF2002', 24 * 60 * 60, 20)
v = tafunc.get_his_volatility(klines, underlying_quote)
print("历史波动率:", v)

quote = api.get_quote("CFFEX.IO2002-C-3550")
bs_serise = BS_VALUE(klines, quote, 0.025)
print("理论价:", list(round(bs_serise['bs_price'], 2)))

klines2 = api.get_kline_serial(["CFFEX.IO2002-C-3550", "CFFEX.IF2002"],
                               24 * 60 * 60, 20)

values = OPTION_VALUE(klines2, quote)
print("内在价值:", list(values["intrins"]))
print("时间价值:", list(values["time"]))

impv = OPTION_IMPV(klines2, quote, 0.025)
print("隐含波动率:", list(round(impv['impv'] * 100, 2)))

greeks = OPTION_GREEKS(klines2, quote, 0.025, impv['impv'])
print("delta:", list(greeks["delta"]))
print("theta:", list(greeks["theta"]))
print("gamma:", list(greeks["gamma"]))
__author__ = "Ringo"

'''
价格动量 策略 (难度:初级)
参考: https://www.shinnytech.com/blog/momentum-strategy/
注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改
'''

from tqsdk import TqAccount, TqApi, TargetPosTask

# 设置指定合约,获取N条K线计算价格动量
SYMBOL = "SHFE.au1912"
N = 15

api = TqApi()
klines = api.get_kline_serial(SYMBOL, 60*60*24, N)
quote = api.get_quote(SYMBOL)
target_pos = TargetPosTask(api, SYMBOL)
position = api.get_position(SYMBOL)

# 编写价格动量函数AR,以前N-1日K线计算价格动量ar


def AR(kline1):
    spread_ho = sum(kline1.high[:-1] - kline1.open[:-1])
    spread_oc = sum(kline1.open[:-1] - kline1.low[:-1])
    # spread_oc 为0时,设置为最小价格跳动值
    if spread_oc == 0:
        spread_oc = quote.price_tick
    ar = (spread_ho/spread_oc)*100
    return ar
Ejemplo n.º 23
0
ls_symbols = ['SHFE.rb1910', 'SHFE.hc1910', 'CZCE.MA909', 'CZCE.TA909', 'DCE.i1909']
# ls_symbols = ['SHFE.fu1909', 'SHFE.bu1912', 'DCE.jd1909']
api = TqApi('SIM')
# api = TqApi(TqSim(), backtest=TqBacktest(start_dt=dt.date(2019,1,2), end_dt=dt.date(2019,1,10)))

dict_quotes = {}
dict_klines = {}
dict_positions = {}
dict_target_pos = {}
dict_update_kline_chan = {}
dict_update_quote_chan = {}

for SYMBOL in ls_symbols:
    dict_quotes[SYMBOL] = api.get_quote(SYMBOL)  # 行情数据
    dict_klines[SYMBOL] = api.get_kline_serial(SYMBOL, duration_seconds=15 * 60)
    dict_positions[SYMBOL] = api.get_position(SYMBOL)
    dict_target_pos[SYMBOL] = TargetPosTask(api, SYMBOL)
    dict_update_kline_chan[SYMBOL] = api.register_update_notify(dict_klines[SYMBOL])
    dict_update_quote_chan[SYMBOL] = api.register_update_notify(dict_quotes[SYMBOL])


async def signal_generator(SYMBOL, strategy):
    """该task应用策略在价格触发时开仓,出发平仓条件时平仓"""
    klines = dict_klines[SYMBOL]
    position = dict_positions[SYMBOL]
    target_pos = dict_target_pos[SYMBOL]
    update_kline_chan = dict_update_kline_chan[SYMBOL]

    while True:
        target_pos_value = 0
Ejemplo n.º 24
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'limin'

from tqsdk import TqApi
'''
画图示例: 在附图中画K线
注意:1 画图功能仅在天勤终端/天勤Vscode插件中生效,请在这两个平台中运行画图相关的代码
     2 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改
'''

api = TqApi()

klines = api.get_kline_serial("SHFE.cu1910", 86400)
klines2 = api.get_kline_serial("SHFE.cu1911", 86400)

# 在附图画出 cu1911 的K线: 需要将open、high、log、close的数据都设置正确
klines["cu1911.open"] = klines2["open"]
klines["cu1911.high"] = klines2["high"]
klines["cu1911.low"] = klines2["low"]
klines["cu1911.close"] = klines2["close"]
klines["cu1911.board"] = "B2"

api.close()  # 需要调用此函数将画图数据发送给天勤并关闭api
Ejemplo n.º 25
0
    return up, up_limit, up_limit2, down, down_limit, down_limit2


acc = TqSim(init_balance=1000000)

# 在创建 api 实例时传入 TqBacktest 就会进入回测模式
api = TqApi(acc,
            backtest=TqBacktest(start_dt=date(2018, 2, 1),
                                end_dt=date(2018, 5, 1)),
            web_gui='http://127.0.0.1:8889')  #

kind1 = 'SHFE.cu1901'
kind2 = 'SHFE.cu1902'

# 获得 m1901 5分钟K线的引用
klines1 = api.get_kline_serial([kind1], 1 * 30, data_length=8000)
klines2 = api.get_kline_serial([kind2], 1 * 30, data_length=8000)
quote1 = api.get_quote(kind1)
quote2 = api.get_quote(kind2)
# # 创建 m1901 的目标持仓 task,该 task 负责调整 m1901 的仓位到指定的目标仓位
target_pos1 = TargetPosTask(api, kind1)
target_pos2 = TargetPosTask(api, kind2)

now1 = datetime.datetime.strptime(quote1.datetime,
                                  "%Y-%m-%d %H:%M:%S.%f")  # 当前quote的时间
now2 = datetime.datetime.strptime(quote2.datetime,
                                  "%Y-%m-%d %H:%M:%S.%f")  # 当前quote的时间
# api.wait_update()
# time1 = time.ctime(klines2.iloc[-1].datetime/(10**9))

while True:
Ejemplo n.º 26
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'limin'

from tqsdk import TqApi, TqAuth
'''
画图示例: 在主图中画线和方框
注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改
'''

api = TqApi(web_gui=True,
            auth=TqAuth("信易账户", "账户密码"))  # web_gui=True, 开启使用 web 界面查看绘图结果的功能
klines = api.get_kline_serial("SHFE.rb2105", 60)

# 由于需要在浏览器中查看绘图结果,因此程序不能退出
while True:
    api.wait_update()  # 当有业务信息发生变化时执行
    # 当最后 1 根柱子最大最小值价差大于 0.05 时,在主图绘制信号
    high = klines.iloc[-1].high
    low = klines.iloc[-1].low
    if high - low > 0.05:
        # 绘制直线, 每一个 id 对应同一条直线
        api.draw_line(klines,
                      -1,
                      high,
                      -1,
                      low,
                      id="box%.0f" % (klines.iloc[-1].id),
                      color=0xaa662244,
                      width=4)
        # 绘制字符串
Ejemplo n.º 27
0
'''

import logging
from tqsdk import TqApi, TqSim, TargetPosTask

SYMBOL = "DCE.jd1905"  # 合约代码
NDAY = 5  # 天数
K1 = 0.2  # 上轨K值
K2 = 0.2  # 下轨K值

api = TqApi(TqSim())
logger = logging.getLogger("TQ")
logger.info("策略开始运行")

quote = api.get_quote(SYMBOL)
klines = api.get_kline_serial(SYMBOL, 24 * 60 * 60)  # 86400使用日线
target_pos = TargetPosTask(api, SYMBOL)


def dual_thrust(quote, klines):
    current_open = klines[-1]["open"]
    HH = max(klines.high[-NDAY - 1:-1])  # N日最高价的最高价
    HC = max(klines.close[-NDAY - 1:-1])  # N日收盘价的最高价
    LC = min(klines.close[-NDAY - 1:-1])  # N日收盘价的最低价
    LL = min(klines.low[-NDAY - 1:-1])  # N日最低价的最低价
    range = max(HH - LC, HC - LL)
    buy_line = current_open + range * K1  # 上轨
    sell_line = current_open - range * K2  # 下轨
    logger.info("当前开盘价: %f, 上轨: %f, 下轨: %f" % (current_open, buy_line, sell_line))
    return buy_line, sell_line
Ejemplo n.º 28
0
'''
连续3根阴线就做空,连续3根阳线就做多,否则空仓
'''

from tqsdk import TqApi, TargetPosTask

api = TqApi()
# 设定连续多少根阳线/阴线
length = 3
# 获得 rb1901 10秒K线的引用, 长度为 length+1
klines = api.get_kline_serial("SHFE.rb1901", 10, data_length=length + 1)
# 创建 rb1901 的目标持仓 task,该 task 负责调整 rb1901 的仓位到指定的目标仓位, offset_priority的用法详见文档
target_pos = TargetPosTask(api, "SHFE.rb1901", offset_priority="今昨开")

while True:
    api.wait_update()
    # 只有在新创建出K线时才判断开平仓条件
    if api.is_changing(klines[-1], "datetime"):
        # 将K线转为pandas.DataFrame, 跳过最后一根刚生成的K线
        df = klines.to_dataframe()[:-1]
        # 比较收盘价和开盘价,判断是阳线还是阴线
        # df["close"] 为收盘价序列, df["open"] 为开盘价序列, ">"(pandas.Series.gt) 返回收盘价是否大于开盘价的一个新序列
        up = df["close"] > df["open"]
        down = df["close"] < df["open"]
        if all(up):
            print("连续阳线: 目标持仓 多头1手")
            # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓
            target_pos.set_target_volume(1)
        elif all(down):
            print("连续阴线: 目标持仓 空头1手")
            target_pos.set_target_volume(-1)
Ejemplo n.º 29
0
'''
菲阿里四价 策略(日内突破策略, 在每日收盘前对所持合约进行平仓)
参考: https://www.shinnytech.com/blog/fairy-four-price/
注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改
'''

from tqsdk import TqApi, TargetPosTask
from datetime import datetime
import time

symbol = "SHFE.cu2002"  # 合约代码
close_hour, close_minute = 14, 50  # 平仓时间

api = TqApi()  # 使用模拟帐号直连行情和交易服务器
quote = api.get_quote(symbol)  # 获取指定合约的盘口行情
klines = api.get_kline_serial(symbol, 24 * 60 * 60)  # 获取日线
position = api.get_position(symbol)  # 持仓信息
target_pos = TargetPosTask(api, symbol)  # 目标持仓

top_rail = klines.high.iloc[-2]  # 上轨: 昨日高点
bottom_rail = klines.low.iloc[-2]  # 下轨: 昨日低点
print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:", klines.close.iloc[-2], ",今日开盘价:", klines.open.iloc[-1])

while True:
    api.wait_update()
    if api.is_changing(klines.iloc[-1], "datetime"):  # 如果产生一根新日线 (即到达下一个交易日): 重新获取上下轨
        top_rail = klines.high.iloc[-2]
        bottom_rail = klines.low.iloc[-2]
        print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:", klines.close.iloc[-2], ",今日开盘价:", klines.open.iloc[-1])

    if api.is_changing(quote, "last_price"):  # 如果行情最新价发生变化
Ejemplo n.º 30
0
Archivo: tq1.py Proyecto: bebeter/pyT
class CuatroStrategy(Process):
    ''''''

    author = 'XIAO LI'

    boll_window = 20
    boll_dev = 1.8
    rsi_window = 14
    rsi_signal = 20
    fast_window = 4
    slow_window = 26
    trailing_long = 0.5
    trailing_short = 0.3
    vol = 1

    boll_up = float('nan')
    boll_down = float('nan')
    rsi_value = float('nan')
    rsi_long = float('nan')
    rsi_short = float('nan')
    fast_ma = float('nan')
    slow_ma = float('nan')
    ma_trend = float('nan')
    intra_trade_high = float('nan')
    intra_trade_low = float('nan')
    long_stop = float('nan')
    short_stop = float('nan')

    parameters = [
        'boll_window'
        'boll_dev'
        'rsi_window'
        'rsi_signal'
        'fast_window'
        'slow_window'
        'trailing_long'
        'trailing_short'
        'vol'
    ]

    variables = [
        'boll_up'
        'boll_down'
        'rsi_value'
        'rsi_long'
        'rsi_short'
        'fast_ma'
        'slow_ma'
        'ma_trend'
        'intra_trade_high'
        'intra_trade_low '
        'long_stop'
        'short_stop'
    ]

    def __init__(self, symbol):
        Process.__init__(self)
        self.symbol = symbol
        self.rsi_long = 50 + self.rsi_signal
        self.rsi_short = 50 - self.rsi_signal
        self.api = TqApi(TqSim(init_balance=50000))
        self.now = datetime.now()
        self.target_pos = TargetPosTask(self.api, self.symbol)
        self.ticks = self.api.get_tick_serial(self.symbol)
        self.klines5 = self.api.get_kline_serial(self.symbol, 60 * 5)
        self.klines15 = self.api.get_kline_serial(self.symbol, 60 * 15)
        self.position = self.api.get_position(self.symbol)

    def on_init(self):
        print(self.now, '策略初始化')

    def on_start(self):
        print(self.now, '策略启动')

    def on_stop(self):
        print(self.now, '策略停止')

    def on_tick(self, ticks):
        if self.api.is_changing(ticks, 'datetime'):

            if self.position.pos_long == 0 and self.position.pos_short == 0:

                if self.ma_trend > 0 and self.rsi_value >= self.rsi_long and ticks.iloc[-1].last_price > self.boll_up:
                    self.target_pos.set_target_volume(self.vol)
                    self.intra_trade_high = ticks.iloc[-1].last_price

                if self.ma_trend < 0 and self.rsi_value <= self.rsi_short and ticks.iloc[
                    -1].last_price < self.boll_down:
                    self.target_pos.set_target_volume(-self.vol)
                    self.intra_trade_low = ticks.iloc[-1].last_price

            elif self.position.pos_long > 0:
                self.intra_trade_high = max(self.intra_trade_high, ticks.iloc[-1].last_price)
                self.long_stop = (self.intra_trade_high - self.trailing_long * (self.boll_up - self.boll_down))
                if ticks.iloc[-1].last_price < self.long_stop:
                    self.target_pos.set_target_volume(0)
                    self.intra_trade_high = float('nan')

            else:
                self.intra_trade_low = min(self.intra_trade_low, ticks.iloc[-1].last_price)
                self.short_stop = (self.intra_trade_low + self.trailing_short * (self.boll_up - self.boll_down))
                if ticks.iloc[-1].last_price > self.short_stop:
                    self.target_pos.set_target_volume(0)
                    self.intra_trade_low = float('nan')

    def on_5minbar(self, klines5):
        if self.api.is_changing(klines5, 'datetime'):
            boll = ta.BOLL(klines5.iloc[:-1], self.boll_window, self.boll_dev).iloc[-1]
            self.boll_up = boll['top']
            self.boll_down = boll['bottom']
            self.rsi_value = ta.RSI(klines5.iloc[:-1], self.rsi_window).iloc[-1]['rsi']

    def on_15minbar(self, klines15):
        if self.api.is_changing(klines15, 'datetime'):

            self.fast_ma = ta.SMA(klines15.iloc[:-1], self.fast_window, 2)
            self.slow_ma = ta.SMA(klines15.iloc[:-1], self.slow_window, 2)

            if self.fast_ma > self.slow_ma:
                self.ma_trend = 1
            elif self.fast_ma < self.slow_ma:
                self.ma_trend = -1
            else:
                self.ma_trend = 0

    def on_order(self):
        if self.api.is_changing(self.api.get_order()):
            pass

    def on_trade(self):
        if self.api.is_changing(self.api.get_trade()):
            pass

    def run(self):
        self.on_init()
        self.on_start()
        while True:
            self.api.wait_update()
            self.on_tick(self.ticks)
            self.on_5minbar(self.klines5)
            self.on_15minbar(self.klines15)
            self.on_order()
            self.on_trade()
        self.on_stop()