コード例 #1
0
ファイル: backtest.py プロジェクト: regis456/tqsdk-python
 async def _md_handler(self):
     async for pack in self.md_recv_chan:
         await self.md_send_chan.send({
                                          "aid": "peek_message"
                                      })
         for d in pack.get("data", []):
             TqApi._merge_diff(self.data, d, self.api._prototype, False)
コード例 #2
0
ファイル: backtest.py プロジェクト: imbugs/tqsdk-python
    def __init__(self, start_dt, end_dt):
        """
        创建天勤回测类

        Args:
            start_dt (date/datetime): 回测起始时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点

            end_dt (date/datetime): 回测结束时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点
        """
        if isinstance(start_dt, datetime):
            self.current_dt = int(start_dt.timestamp() * 1e9)
        elif isinstance(start_dt, date):
            self.current_dt = TqApi._get_trading_day_start_time(
                int(
                    datetime(start_dt.year, start_dt.month,
                             start_dt.day).timestamp()) * 1000000000)
        else:
            raise Exception(
                "回测起始时间(start_dt)类型 %s 错误, 请检查 start_dt 数据类型是否填写正确" %
                (type(start_dt)))
        if isinstance(end_dt, datetime):
            self.end_dt = int(end_dt.timestamp() * 1e9)
        elif isinstance(end_dt, date):
            self.end_dt = TqApi._get_trading_day_end_time(
                int(
                    datetime(end_dt.year, end_dt.month,
                             end_dt.day).timestamp()) * 1000000000)
        else:
            raise Exception("回测结束时间(end_dt)类型 %s 错误, 请检查 end_dt 数据类型是否填写正确" %
                            (type(end_dt)))
コード例 #3
0
ファイル: callback.py プロジェクト: Fire89/Use_Cython_for_CTP
class DemoCallback:
    def __init__(self):
        self.api = TqApi()
        self.quote = self.api.get_quote("SHFE.cu1805")

    def on_data_update(self):
        if self.quote.get("last_price", 0) > 1000:
            self.api.insert_order(symbol="SHFE.cu1805",
                                  direction="BUY",
                                  offset="OPEN",
                                  volume=1,
                                  limit_price=30000)

    def run(self):
        self.api.run(self.on_data_update)
コード例 #4
0
ファイル: backtest.py プロジェクト: xtsfullstack/tqsdk-python
    def __init__(self, start_dt, end_dt):
        """
        创建天勤回测类

        Args:
            start_dt (date/datetime): 回测起始时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点

            end_dt (date/datetime): 回测结束时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点
        """
        if isinstance(start_dt, datetime):
            self.current_dt = int(start_dt.timestamp()*1e9)
        else:
            self.current_dt = TqApi._get_trading_day_start_time(int(datetime(start_dt.year, start_dt.month, start_dt.day).timestamp())*1000000000)
        if isinstance(end_dt, datetime):
            self.end_dt = int(end_dt.timestamp()*1e9)
        else:
            self.end_dt = TqApi._get_trading_day_end_time(int(datetime(end_dt.year, end_dt.month, end_dt.day).timestamp())*1000000000)
コード例 #5
0
ファイル: tqSpider.py プロジェクト: yangguang760/fooltrader
def scrawl_day_tick(date, ex):
    agg = agg_future_dayk()
    logging.info("start filter existed symbols")
    path = TICK_PATH
    logging.info("start getting tick data")
    api = TqApi(account=TqSim())
    logging.info(ex + ": start getting tick")
    currentYearData = agg.getCurrentYearData(ex)
    currentYearData = currentYearData[currentYearData['date'] == date]
    pathpair = list(
        map(
            lambda x: (x[1].strftime('%Y%m%d') + "-" + x[0], x[0],
                       datetime.utcfromtimestamp(x[1].timestamp())),
            currentYearData[['symbol', 'date']].values))
    trading_dates = get_trading_calendar(security_type="future",
                                         exchange="shfe")
    tdates = {}
    for i in range(len(trading_dates)):
        if i > 0:
            tdates[datetime.strptime(trading_dates[i],
                                     '%Y%m%d')] = datetime.strptime(
                                         trading_dates[i - 1], '%Y%m%d')
    for i in pathpair:
        if i[1].startswith("sc"):
            continue
        the_dir1 = os.path.join(path, ex.upper(), str(i[2].year))
        if not os.path.exists(the_dir1):
            os.makedirs(the_dir1)
        the_dir = os.path.join(path, ex.upper(), str(i[2].year),
                               i[0] + ".csv.gz")
        the_dir2 = os.path.join(path, ex.upper(), str(i[2].year),
                                i[0] + ".csv")
        # print(the_dir)
        if not os.path.exists(the_dir):
            td = DataDownloader(api,
                                symbol_list=[ex.upper() + "." + i[1]],
                                dur_sec=0,
                                start_dt=tdates[i[2]] + timedelta(hours=17),
                                end_dt=i[2] + timedelta(hours=15),
                                csv_file_name=the_dir2)
            while not td.is_finished():
                api.wait_update()
                # print("progress:  tick:%.2f%%" %  td.get_progress())
            print("done:" + the_dir)
    logging.info(ex + ": complete getting tick")
コード例 #6
0
ファイル: task.py プロジェクト: Fire89/Use_Cython_for_CTP
class DemoTask:
    def __init__(self):
        self.api = TqApi()
        self.tm = TaskManager(self.api)

    def task_main(self):
        print("start")
        quote = self.api.get_quote("SHFE.cu1805")
        while True:
            wait_result = yield {
                "QUOTE_CHANGED": lambda: self.api.is_changing(quote),
                "TIMEOUT": 0.2,
            }
            if wait_result["QUOTE_CHANGED"]:
                print("Quote", quote)
            if wait_result["TIMEOUT"]:
                print("Timeout")

    def run(self):
        self.tm.start_task(self.task_main())
        self.api.run()
コード例 #7
0
ファイル: tqSpider.py プロジェクト: yangguang760/fooltrader
def scrawl_single_tick(i, path, ex, tdates):
    the_dir1 = os.path.join(path, ex.upper(), str(i[2].year))
    if not os.path.exists(the_dir1):
        os.makedirs(the_dir1)
    the_dir = os.path.join(path, ex.upper(), str(i[2].year), i[0] + ".csv.gz")
    the_dir2 = os.path.join(path, ex.upper(), str(i[2].year), i[0] + ".csv")
    if not os.path.exists(the_dir):
        print(the_dir)
        print(i)
        print(tdates[i[2]])
        print(i[2])
        api = TqApi(account=TqSim())
        # api = TqApi(account=TqSim(),url="ws://192.168.56.1:7777")
        td = DataDownloader(api,
                            symbol_list=[ex.upper() + "." + i[1]],
                            dur_sec=0,
                            start_dt=tdates[i[2]] + timedelta(hours=17),
                            end_dt=i[2] + timedelta(hours=16),
                            csv_file_name=the_dir2)
        while not td.is_finished():
            api.wait_update()
            # print("progress:  tick:%.2f%%" %  td.get_progress())
        print("done:" + the_dir)
        api.close()
        with open(the_dir2, 'rb') as f:
            with gzip.GzipFile(filename=the_dir2 + ".gz",
                               mode='w',
                               compresslevel=9) as gf:
                content = f.read()
                gf.write(content)
        os.remove(the_dir2)
        del td
        del api
        gc.collect()
コード例 #8
0
class DemoSpread:
    def __init__(self):
        self.api = TqApi()
        self.tm = TaskManager(self.api)

    def task_main(self):
        print ("start")
        symbol_a = "SHFE.cu1805"
        symbol_b = "SHFE.cu1806"
        quote_a = self.api.get_quote(symbol_a)
        quote_b = self.api.get_quote(symbol_b)
        buy_open_spread = 50000
        sell_close_spread = -70000
        max_volume = 5
        long_volume = 0
        while True:
            wait_result = yield {
                "BUY_OPEN": lambda: long_volume == 0 and quote_a["ask_price1"] - quote_b["bid_price1"] < buy_open_spread,
                "SELL_CLOSE": lambda: long_volume > 0 and quote_a["bid_price1"] - quote_b["ask_price1"] > sell_close_spread,
            }
            if wait_result["BUY_OPEN"]:
                task_a = self.tm.start_task(make_order_until_all_matched(self.api, symbol=symbol_a, direction="BUY", offset="OPEN", volume=max_volume))
                task_b = self.tm.start_task(make_order_until_all_matched(self.api, symbol=symbol_b, direction="SELL", offset="OPEN", volume=max_volume))
                long_volume = max_volume
            if wait_result["SELL_CLOSE"]:
                task_a = self.tm.start_task(make_order_until_all_matched(self.api, symbol=symbol_a, direction="SELL", offset="CLOSE", volume=max_volume))
                task_b = self.tm.start_task(make_order_until_all_matched(self.api, symbol=symbol_b, direction="BUY", offset="CLOSE", volume=max_volume))
                long_volume = 0
            wait_subtask_finish = yield {
                "ANY_TASK_ERROR": lambda: self.tm.get_error(task_a) or self.tm.get_error(task_b),
                "BOTH_TASK_FINSISH": lambda: self.tm.is_finish(task_a) and self.tm.is_finish(task_b),
            }
            if wait_subtask_finish["ANY_TASK_ERROR"]:
                break
        print ("finish")

    def run(self):
        self.tm.start_task(self.task_main())
        self.api.run()
コード例 #9
0
class DemoMa:
    def __init__(self):
        self.api = TqApi()
        self.tm = TaskManager(self.api)

    def task_main(self):
        print("start")
        symbol = "SHFE.cu1805"
        kline_serial_5s = self.api.get_kline_serial(symbol, 5)
        kline_serial_1m = self.api.get_kline_serial(symbol, 60)
        while True:
            yield {
                "KLINE_DATA_UPDATED":
                lambda: self.api.is_changing(kline_serial_1m) or self.api.
                is_changing(kline_serial_5s),
            }
            # 计算最近3根5秒线均价
            average_price_15s = (kline_serial_5s[-1]["close"] +
                                 kline_serial_5s[-2]["close"] +
                                 kline_serial_5s[-3]["close"]) / 3
            # 计算最近30根1分钟线均价
            average_price_30m = sum(kline_serial_1m.close[-30:]) / 30
            # 如果条件符合
            print("average_price_15s", average_price_15s, "average_price_30m",
                  average_price_30m)
            if average_price_15s > average_price_30m:
                self.api.insert_order(symbol=symbol,
                                      direction="BUY",
                                      offset="OPEN",
                                      volume=1,
                                      limit_price=5000)
        print("finish")

    def run(self):
        self.tm.start_task(self.task_main())
        self.api.run()
コード例 #10
0
def run():
    #获取命令行参数
    parser = argparse.ArgumentParser()
    parser.add_argument('--source_file')
    parser.add_argument('--instance_id')
    parser.add_argument('--instance_file')
    parser.add_argument('--tq_pid')
    args = parser.parse_args()
    TqMonitorThread(int(args.tq_pid)).start()

    # api
    api = TqApi(args.instance_id)
    try:
        sys.stdout = PrintWriter(api.send_chan, args.instance_id)
        # log
        logger = logging.getLogger("TQ")
        logger.setLevel(logging.INFO)
        th = TqRunLogger(api.send_chan, args.instance_id)
        th.setLevel(logging.INFO)
        logger.addHandler(th)

        try:
            #加载策略文件
            file_path, file_name = os.path.split(args.source_file)
            sys.path.insert(0, file_path)
            module_name = file_name[:-3]

            param_list = []
            # 加载或输入参数
            try:
                # 从文件读取参数表
                with open(args.instance_file, "rt") as param_file:
                    instance = json.load(param_file)
                    param_list = instance.get("param_list", [])
            except Exception:
                # 获取用户代码中的参数表
                def _fake_api_for_param_list(*args, **kwargs):
                    m = sys.modules[module_name]
                    for k, v in m.__dict__.items():
                        if k.upper() != k:
                            continue
                        if isinstance(v, datetime.date) or isinstance(v, datetime.time) \
                                or isinstance(v, int) or isinstance(v, float) or isinstance(v, str):
                            param_list.append([k, v])
                    raise Exception()

                tqsdk.TqApi = _fake_api_for_param_list
                try:
                    importlib.import_module(module_name)
                except Exception:
                    pass

                param_list = input_param(param_list)
                if param_list is None:
                    return
                with open(args.instance_file, "wt") as param_file:
                    json.dump(
                        {
                            "instance_id": args.instance_id,
                            "strategy_file_name": args.source_file,
                            "desc": json.dumps(param_list),
                            "param_list": param_list,
                        }, param_file)
            api.send_chan.send_nowait({
                "aid": "desc",
                "instance_id": args.instance_id,
                "status": "RUNNING",
                "desc": json.dumps(param_list)
            })

            # 拉起实例并直接执行
            def _fake_api_for_launch(*args, **kwargs):
                m = sys.modules[module_name]
                for k, v in param_list:
                    m.__dict__[k] = v
                return api

            tqsdk.TqApi = _fake_api_for_launch
            __import__(module_name)

        except ModuleNotFoundError:
            logger.exception("加载策略文件失败")
        except IndentationError:
            logger.exception("策略文件缩进格式错误")
        except Exception as e:
            logger.exception("策略运行中遇到异常", exc_info=True)
    finally:
        if not api.loop.is_closed():
            api.close()
コード例 #11
0
def run():
    #获取命令行参数
    parser = argparse.ArgumentParser()
    parser.add_argument('--source_file')
    parser.add_argument('--instance_id')
    parser.add_argument('--instance_file')
    args = parser.parse_args()

    # api
    api = TqApi(TqAccount("", args.instance_id, ""),
                url="ws://127.0.0.1:7777/" + args.instance_id)
    with closing(api):
        # log
        logger = logging.getLogger("TQ")
        logger.setLevel(logging.INFO)
        th = TqRunLogger(api.send_chan, args.instance_id)
        th.setLevel(logging.INFO)
        logger.addHandler(th)

        try:
            #加载策略文件
            file_path, file_name = os.path.split(args.source_file)
            sys.path.insert(0, file_path)
            module_name = file_name[:-3]

            param_list = []
            # 加载或输入参数
            try:
                # 从文件读取参数表
                with open(args.instance_file, "rt") as param_file:
                    instance = json.load(param_file)
                    param_list = instance.get("param_list", [])
            except IOError:
                # 获取用户代码中的参数表
                def _fake_api_for_param_list(*args, **kwargs):
                    m = sys.modules[module_name]
                    for k, v in m.__dict__.items():
                        if k.upper() != k:
                            continue
                        param_list.append([k, v])
                    raise Exception()

                tqsdk.TqApi = _fake_api_for_param_list
                try:
                    importlib.import_module(module_name)
                except Exception:
                    pass

                param_list = input_param(param_list)
                if param_list is None:
                    return
                with open(args.instance_file, "wt") as param_file:
                    json.dump(
                        {
                            "instance_id": args.instance_id,
                            "strategy_file_name": args.source_file,
                            "desc": json.dumps(param_list),
                            "param_list": param_list,
                        }, param_file)
            api.send_chan.send_nowait({
                "aid": "status",
                "instance_id": args.instance_id,
                "status": "RUNNING",
                "desc": json.dumps(param_list)
            })

            # 拉起实例并直接执行
            def _fake_api_for_launch(*args, **kwargs):
                m = sys.modules[module_name]
                for k, v in param_list:
                    m.__dict__[k] = v
                return api

            tqsdk.TqApi = _fake_api_for_launch
            importlib.import_module(module_name)

        except ModuleNotFoundError:
            logger.exception("加载策略文件失败")
        except IndentationError:
            logger.exception("策略文件缩进格式错误")
        except Exception as e:
            logger.exception("策略运行中遇到异常", exc_info=True)
コード例 #12
0
def dual_thrust(quote, klines):
    current_open = quote["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  # 下轨

    print("当前开盘价:", current_open, "\n上轨:", buy_line, "\n下轨:", sell_line)
    return buy_line, sell_line


api = TqApi("SIM")
quote = api.get_quote(symbol)
klines = api.get_kline_serial(symbol, 24 * 60 * 60)  # 86400使用日线
target_pos = TargetPosTask(api, symbol)
buy_line, sell_line = dual_thrust(quote, klines)  # 获取上下轨

while True:
    api.wait_update()
    if api.is_changing(klines[-1], "datetime") or api.is_changing(
            quote, "open"):  # 新产生一根日线或开盘价发生变化: 重新计算上下轨
        buy_line, sell_line = dual_thrust(quote, klines)

    if api.is_changing(quote, "last_price"):
        print("最新价变化", quote["last_price"], end=':')
        if quote["last_price"] > buy_line:  # 高于上轨
            print("高于上轨,目标持仓 多头3手")
コード例 #13
0
    def __init__(self, api, symbol_list, dur_sec, start_dt, end_dt,
                 csv_file_name):
        """
        创建历史数据下载器实例

        Args:
            api (TqApi): TqApi实例,该下载器将使用指定的api下载数据

            symbol_list (str/list of str): 需要下载数据的合约代码,当指定多个合约代码时将其他合约按第一个合约的交易时间对齐

            dur_sec (int): 数据周期,以秒为单位。例如: 1分钟线为60,1小时线为3600,日线为86400,Tick数据为0

            start_dt (date/datetime): 起始时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点

            end_dt (date/datetime): 结束时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点

            csv_file_name (str): 输出csv的文件名

        Example::

            from datetime import datetime, date
            from contextlib import closing
            from tqsdk import TqApi, TqSim
            from tqsdk.tools import DataDownloader

            api = TqApi(TqSim())
            download_tasks = {}
            # 下载从 2018-01-01 到 2018-09-01 的 SR901 日线数据
            download_tasks["SR_daily"] = DataDownloader(api, symbol_list="CZCE.SR901", dur_sec=24*60*60,
                                start_dt=date(2018, 1, 1), end_dt=date(2018, 9, 1), csv_file_name="SR901_daily.csv")
            # 下载从 2017-01-01 到 2018-09-01 的 rb主连 5分钟线数据
            download_tasks["rb_5min"] = DataDownloader(api, symbol_list="*****@*****.**", dur_sec=5*60,
                                start_dt=date(2017, 1, 1), end_dt=date(2018, 9, 1), csv_file_name="rb_5min.csv")
            # 下载从 2018-01-01凌晨6点 到 2018-06-01下午4点 的 cu1805,cu1807,IC1803 分钟线数据,所有数据按 cu1805 的时间对齐
            # 例如 cu1805 夜盘交易时段, IC1803 的各项数据为 N/A
            # 例如 cu1805 13:00-13:30 不交易, 因此 IC1803 在 13:00-13:30 之间的K线数据会被跳过
            download_tasks["cu_min"] = DataDownloader(api, symbol_list=["SHFE.cu1805", "SHFE.cu1807", "CFFEX.IC1803"], dur_sec=60,
                                start_dt=datetime(2018, 1, 1, 6, 0 ,0), end_dt=datetime(2018, 6, 1, 16, 0, 0), csv_file_name="cu_min.csv")
            # 下载从 2018-05-01凌晨0点 到 2018-06-01凌晨0点 的 T1809 盘口Tick数据
            download_tasks["T_tick"] = DataDownloader(api, symbol_list=["CFFEX.T1809"], dur_sec=0,
                                start_dt=datetime(2018, 5, 1), end_dt=datetime(2018, 6, 1), csv_file_name="T1809_tick.csv")
            # 使用with closing机制确保下载完成后释放对应的资源
            with closing(api):
                while not all([v.is_finished() for v in download_tasks.values()]):
                    api.wait_update()
                    print("progress: ", { k:("%.2f%%" % v.get_progress()) for k,v in download_tasks.items() })
        """
        self.api = api
        if isinstance(start_dt, datetime):
            self.start_dt_nano = int(start_dt.timestamp() * 1e9)
        else:
            self.start_dt_nano = TqApi._get_trading_day_start_time(
                int(
                    datetime(start_dt.year, start_dt.month,
                             start_dt.day).timestamp()) * 1000000000)
        if isinstance(end_dt, datetime):
            self.end_dt_nano = int(end_dt.timestamp() * 1e9)
        else:
            self.end_dt_nano = TqApi._get_trading_day_end_time(
                int(
                    datetime(end_dt.year, end_dt.month,
                             end_dt.day).timestamp()) * 1000000000)
        self.current_dt_nano = self.start_dt_nano
        self.symbol_list = symbol_list if isinstance(symbol_list,
                                                     list) else [symbol_list]
        self.dur_nano = dur_sec * 1000000000
        if self.dur_nano == 0 and len(self.symbol_list) != 1:
            raise Exception("Tick序列不支持多合约")
        self.csv_file_name = csv_file_name
        self.task = self.api.create_task(self._download_data())
コード例 #14
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from datetime import datetime
from tqsdk.api import TqApi
from tqsdk.tools.downloader import DataDownloader

import getopt, os, sys, re

api = TqApi("SIM")

# 下载从 2018-01-01 到 2018-06-01 的 cu1805,cu1807,IC1803 分钟线数据,所有数据按 cu1805 的时间对齐
# 例如 cu1805 夜盘交易时段, IC1803 的各项数据为 N/A
# 例如 cu1805 13:00-13:30 不交易, 因此 IC1803 在 13:00-13:30 之间的K线数据会被跳过
#


def incept_config():
    config = {'output_dir': os.getcwd()}

    pattern = re.compile(r'\D*')

    def usage():
        print(("Usage:%s [-s] [--data_source]" % sys.argv[0]))
        # print "-s --data_source, is the path of data file."
        print("-o --output_dir, is the output directory. optional.")
        print("-n --name, is the instrument id. optional.")
        print(
            "-g --granularities, default are 2,5,10,30,60 minutes, delimiter is a comma. optional."
        )
コード例 #15
0
ファイル: backtest.py プロジェクト: imbugs/tqsdk-python
 async def _gen_serial(self, ins, dur):
     """k线/tick 序列的 async generator, yield 出来的行情数据带有时间戳, 因此 _send_diff 可以据此归并"""
     # 先定位左端点, focus_datetime 是 lower_bound ,这里需要的是 upper_bound
     # 因此将 view_width 和 focus_position 设置成一样,这样 focus_datetime 所对应的 k线刚好位于屏幕外
     chart_info = {
         "aid":
         "set_chart",
         "chart_id":
         TqApi._generate_chart_id("backtest", ins, dur // 1000000000),
         "ins_list":
         ins,
         "duration":
         dur,
         "view_width":
         8964,
         "focus_datetime":
         int(self.current_dt),
         "focus_position":
         8964,
     }
     chart = TqApi._get_obj(self.data, ["charts", chart_info["chart_id"]])
     current_id = None  # 当前数据指针
     serial = TqApi._get_obj(
         self.data,
         ["klines", ins, str(dur)] if dur != 0 else ["ticks", ins])
     async with TqChan(self.api, last_only=True) as update_chan:
         serial["_listener"].add(update_chan)
         chart["_listener"].add(update_chan)
         await self.md_send_chan.send(chart_info.copy())
         try:
             async for _ in update_chan:
                 if not (chart_info.items() <= TqApi._get_obj(
                         chart, ["state"]).items()):
                     # 当前请求还没收齐回应, 不应继续处理
                     continue
                 left_id = chart.get("left_id", -1)
                 right_id = chart.get("right_id", -1)
                 last_id = serial.get("last_id", -1)
                 if (left_id == -1 and right_id == -1) or last_id == -1:
                     # 定位信息还没收到, 或数据序列还没收到
                     continue
                 if self.data.get("mdhis_more_data", True):
                     self.data["_listener"].add(update_chan)
                     continue
                 else:
                     self.data["_listener"].discard(update_chan)
                 if current_id is None:
                     current_id = max(left_id, 0)
                 while True:
                     if current_id > last_id:
                         # 当前 id 已超过 last_id
                         return
                     if current_id - chart_info.get("left_kline_id",
                                                    left_id) > 5000:
                         # 当前 id 已超出订阅范围, 需重新订阅后续数据
                         chart_info["left_kline_id"] = current_id
                         chart_info.pop("focus_datetime", None)
                         chart_info.pop("focus_position", None)
                         await self.md_send_chan.send(chart_info.copy())
                     if current_id > right_id:
                         break
                     item = serial["data"].get(str(current_id), {}).copy()
                     del item["_path"]
                     del item["_listener"]
                     if dur == 0:
                         diff = {
                             "ticks": {
                                 ins: {
                                     "last_id": current_id,
                                     "data": {
                                         str(current_id): item,
                                         str(current_id - 8964): None,
                                     }
                                 }
                             }
                         }
                         if item["datetime"] > self.end_dt:  # 超过结束时间
                             return
                         yield item[
                             "datetime"], diff, self._get_quotes_from_tick(
                                 item)
                     else:
                         diff = {
                             "klines": {
                                 ins: {
                                     str(dur): {
                                         "last_id": current_id,
                                         "data": {
                                             str(current_id): {
                                                 "datetime":
                                                 item["datetime"],
                                                 "open": item["open"],
                                                 "high": item["open"],
                                                 "low": item["open"],
                                                 "close": item["open"],
                                                 "volume": 0,
                                                 "open_oi": item["open_oi"],
                                                 "close_oi":
                                                 item["open_oi"],
                                             },
                                             str(current_id - 8964): None,
                                         }
                                     }
                                 }
                             }
                         }
                         timestamp = item[
                             "datetime"] if dur < 86400000000000 else TqApi._get_trading_day_start_time(
                                 item["datetime"])
                         if timestamp > self.end_dt:  # 超过结束时间
                             return
                         yield timestamp, diff, None
                         diff = {
                             "klines": {
                                 ins: {
                                     str(dur): {
                                         "data": {
                                             str(current_id): item,
                                         }
                                     }
                                 }
                             }
                         }
                         timestamp = item[
                             "datetime"] + dur - 1000 if dur < 86400000000000 else TqApi._get_trading_day_end_time(
                                 item["datetime"])
                         if timestamp > self.end_dt:  # 超过结束时间
                             return
                         yield timestamp, diff, self._get_quotes_from_kline(
                             self.data["quotes"][ins], timestamp, item)
                     current_id += 1
         finally:
             # 释放chart资源
             chart_info["ins_list"] = ""
             await self.md_send_chan.send(chart_info.copy())
コード例 #16
0
ファイル: callback.py プロジェクト: Fire89/Use_Cython_for_CTP
 def __init__(self):
     self.api = TqApi()
     self.quote = self.api.get_quote("SHFE.cu1805")
コード例 #17
0
ファイル: t41.py プロジェクト: wocclyl/tqsdk-python
#!/usr/bin/env python
#  -*- coding: utf-8 -*-

from tqsdk.api import TqApi

api = TqApi("SIM")
# 开仓两手并等待完成
order = api.insert_order(symbol="SHFE.rb1901",
                         direction="BUY",
                         offset="OPEN",
                         limit_price=4310,
                         volume=2)
while order["status"] != "FINISHED":
    api.wait_update()
print("已开仓")
# 平今两手并等待完成
order = api.insert_order(symbol="SHFE.rb1901",
                         direction="SELL",
                         offset="CLOSETODAY",
                         limit_price=3925,
                         volume=2)
while order["status"] != "FINISHED":
    api.wait_update()
print("已平今")
# 关闭api,释放相应资源
api.close()
コード例 #18
0
 def __init__(self):
     self.api = TqApi()
     self.tm = TaskManager(self.api)
コード例 #19
0
ファイル: bardl.py プロジェクト: pqctp/quotesys-1
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from datetime import datetime
from tqsdk.api import TqApi
from tqsdk.tools.downloader import DataDownloader

import getopt, os, sys, re
url = 'ws://192.168.1.20:7777'
api = TqApi("SIM", url)

# 下载从 2018-01-01 到 2018-06-01 的 cu1805,cu1807,IC1803 分钟线数据,所有数据按 cu1805 的时间对齐
# 例如 cu1805 夜盘交易时段, IC1803 的各项数据为 N/A
# 例如 cu1805 13:00-13:30 不交易, 因此 IC1803 在 13:00-13:30 之间的K线数据会被跳过
#


def incept_config():
    config = {'output_dir': os.getcwd()}

    pattern = re.compile(r'\D*')

    def usage():
        print("Usage:%s [-s] [--data_source]" % sys.argv[0])
        # print "-s --data_source, is the path of data file."
        print("-o --output_dir, is the output directory. optional.")
        print("-n --name, is the instrument id. optional.")
        print(
            "-g --granularities, default are 2,5,10,30,60 minutes, delimiter is a comma. optional."
        )
コード例 #20
0
ファイル: t30.py プロジェクト: wocclyl/tqsdk-python
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from tqsdk.api import TqApi
import datetime

api = TqApi("SIM")
# 获得cu1812 tick序列的引用
ticks = api.get_tick_serial("SHFE.cu1812")
# 获得cu1812 10秒K线的引用
klines = api.get_kline_serial("SHFE.cu1812", 10)

while True:
    api.wait_update()
    # 判断整个tick序列是否有变化
    if api.is_changing(ticks):
        # ticks[-1]返回序列中最后一个tick
        print("tick变化", ticks[-1])
    # 判断最后一根K线的时间是否有变化,如果发生变化则表示新产生了一根K线
    if api.is_changing(klines[-1], "datetime"):
        # datetime: 自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数
        print("新K线",
              datetime.datetime.fromtimestamp(klines[-1]["datetime"] / 1e9))
    # 判断最后一根K线的收盘价是否有变化
    if api.is_changing(klines[-1], "close"):
        # klines.close返回收盘价序列
        print("K线变化",
              datetime.datetime.fromtimestamp(klines[-1]["datetime"] / 1e9),
              klines.close[-1])
コード例 #21
0
ファイル: t70.py プロジェクト: wocclyl/tqsdk-python
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from tqsdk.api import TqApi
from tqsdk.lib import TargetPosTask
'''
如果当前价格大于10秒K线的MA15则开多仓
如果小于则平仓
'''
api = TqApi("SIM")
# 获得 m1901 10秒K线的引用
klines = api.get_kline_serial("DCE.m1901", 10)
# 创建 m1901 的目标持仓 task,该 task 负责调整 m1901 的仓位到指定的目标仓位
target_pos = TargetPosTask(api, "DCE.m1901")

while True:
    api.wait_update()
    if api.is_changing(klines):
        ma = sum(klines.close[-15:]) / 15
        print("最新价", klines.close[-1], "MA", ma)
        if klines.close[-1] > ma:
            print("最新价大于MA: 目标多头5手")
            # 设置目标持仓为多头5手
            target_pos.set_target_volume(5)
        elif klines.close[-1] < ma:
            print("最新价小于MA: 目标空仓")
            # 设置目标持仓为空仓
            target_pos.set_target_volume(0)
コード例 #22
0
ファイル: t60.py プロジェクト: wocclyl/tqsdk-python
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from tqsdk.api import TqApi

'''
如果当前价格大于10秒K线的MA15则开多仓
如果小于则平仓
'''
api = TqApi("SIM")
# 获得 m1901 10秒K线的引用
klines = api.get_kline_serial("DCE.m1901", 10)

# 判断开仓条件
while True:
    api.wait_update()
    if api.is_changing(klines):
        ma = sum(klines.close[-15:])/15
        print("最新价", klines.close[-1], "MA", ma)
        if klines.close[-1] > ma:
            print("最新价大于MA: 市价开仓")
            api.insert_order(symbol="DCE.m1901", direction="BUY", offset="OPEN", volume=5)
            break
# 判断平仓条件
while True:
    api.wait_update()
    if api.is_changing(klines):
        ma = sum(klines.close[-15:])/15
        print("最新价", klines.close[-1], "MA", ma)
        if klines.close[-1] < ma:
コード例 #23
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-

from tqsdk.api import TqApi


#时间转换函数
def timeChange(second=0, minute=0, hour=0):
    return second + minute * 60 + hour * 3600


api = TqApi("SIM")
ticks = api.get_tick_serial("SHFE.rb1901")
K_Line_one = api.get_kline_serial("SHFE.rb1901",
                                  timeChange(0, 3))  #负责大周期突破判断(时间自己判断)
K_Line_two = api.get_kline_serial("SHFE.rb1901", timeChange(0,
                                                            15))  #负责止盈(时间自己判断)
K_Line_three = api.get_kline_serial("SHFE.rb1901",
                                    timeChange(0, 0, 1))  #负责止损(时间自己判断)
signBuy = 0
signSell = 0
cciValue = 0
sarLittleUp = [0]
sarLittleDown = [0]
sarBigUp = [0]
sarBigDown = [0]


#震荡指标(任意震荡指标 CCI默认n = 20)
def CCI(n=20):
    TP = ((K_Line_one[-1]["close"] + K_Line_one[-1]["low"] +
コード例 #24
0
ファイル: t40.py プロジェクト: dadaxiaoxiaobaba/tqsdk-python
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from tqsdk.api import TqApi

api = TqApi("SIM")
# 获得 cu1812 的持仓引用,当持仓有变化时 position 中的字段会对应更新
position = api.get_position("SHFE.cu1812")
# 获得资金账户引用,当账户有变化时 account 中的字段会对应更新
account = api.get_account()
# 下单并返回委托单的引用,当该委托单有变化时 order 中的字段会对应更新
order = api.insert_order(symbol="SHFE.cu1812",
                         direction="BUY",
                         offset="OPEN",
                         volume=5)

while True:
    api.wait_update()
    if api.is_changing(order, ["status", "volume_orign", "volume_left"]):
        print("单状态: %s, 已成交: %d 手" %
              (order["status"], order["volume_orign"] - order["volume_left"]))
    if api.is_changing(position, "volume_long_today"):
        print("今多头: %d 手" % (position["volume_long_today"]))
    if api.is_changing(account, "available"):
        print("可用资金: %.2f" % (account["available"]))
コード例 #25
0
ファイル: t71.py プロジェクト: wocclyl/tqsdk-python
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'yanqiong'

from tqsdk.api import TqApi
from tqsdk.lib import TargetPosTask

'''
连续3根阴线就做空,连续3根阳线就做多,否则空仓
'''

api = TqApi("SIM")
# 设定连续多少根阳线/阴线
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手")
コード例 #26
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from tqsdk.api import TqApi
from tqsdk.lib import TargetPosTask
'''
价差回归
当近月-远月的价差大于200时做空近月,做多远月
当价差小于150时平仓
'''
api = TqApi("SIM")
quote_near = api.get_quote("SHFE.rb1810")
quote_deferred = api.get_quote("SHFE.rb1901")
# 创建 rb1810 的目标持仓 task,该 task 负责调整 rb1810 的仓位到指定的目标仓位
target_pos_near = TargetPosTask(api, "SHFE.rb1810")
# 创建 rb1901 的目标持仓 task,该 task 负责调整 rb1901 的仓位到指定的目标仓位
target_pos_deferred = TargetPosTask(api, "SHFE.rb1901")

while True:
    api.wait_update()
    if api.is_changing(quote_near) or api.is_changing(quote_deferred):
        spread = quote_near["last_price"] - quote_deferred["last_price"]
        print("当前价差:", spread)
        if spread > 200:
            print("目标持仓: 空近月,多远月")
            # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓
            target_pos_near.set_target_volume(-1)
            target_pos_deferred.set_target_volume(1)
        elif spread < 150:
            print("目标持仓: 空仓")
コード例 #27
0
 async def _ws_handler(self):
     async for pack in self.ws_recv_chan:
         for d in pack.get("data", []):
             TqApi._merge_diff(self.data, d, self.api.prototype)
コード例 #28
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from datetime import datetime
from contextlib import closing
from tqsdk.api import TqApi
from tqsdk.tools.downloader import DataDownloader

api = TqApi("SIM")
# 下载从 2018-01-01凌晨6点 到 2018-06-01下午4点 的 cu1805 分钟线数据
kd = DataDownloader(api,
                    symbol_list="SHFE.cu1805",
                    dur_sec=60,
                    start_dt=datetime(2018, 1, 1, 6, 0, 0),
                    end_dt=datetime(2018, 6, 1, 16, 0, 0),
                    csv_file_name="kline.csv")
# 下载从 2018-05-01凌晨0点 到 2018-07-01凌晨0点 的 T1809 盘口Tick数据
td = DataDownloader(api,
                    symbol_list="CFFEX.T1809",
                    dur_sec=0,
                    start_dt=datetime(2018, 5, 1),
                    end_dt=datetime(2018, 7, 1),
                    csv_file_name="tick.csv")
# 使用with closing机制确保下载完成后释放对应的资源
with closing(api):
    while not kd.is_finished() or not td.is_finished():
        api.wait_update()
        print("progress: kline: %.2f%% tick:%.2f%%" %
              (kd.get_progress(), td.get_progress()))
コード例 #29
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'chengzhi'

from tqsdk.api import TqApi

api = TqApi("SIM")
quote = api.get_quote("SHFE.cu1812")

while True:
    api.wait_update()
    # 如果 cu1812 的任何字段有变化,is_changing就会返回 True
    if api.is_changing(quote):
        print(quote)
    # 只有当 cu1812 的最新价有变化,is_changing才会返回 True
    if api.is_changing(quote, "last_price"):
        print("最新价变化", quote["last_price"])
    # 当 cu1812 的买1价/买1量/卖1价/卖1量中任何一个有变化,is_changing都会返回 True
    if api.is_changing(
            quote, ["ask_price1", "ask_volume1", "bid_price1", "bid_volume1"]):
        print("盘口变化", quote["ask_price1"], quote["ask_volume1"],
              quote["bid_price1"], quote["bid_volume1"])
コード例 #30
0
ファイル: y_tools.py プロジェクト: Fire89/Use_Cython_for_CTP
class Y_Base:
    def __init__(self):
        self.api = TqApi()
        self.tm = TaskManager(self.api)        

    def task_main(self):
        """
        def test():
            max_volume = 1
            while True:
                wait_result = yield {
                    "BUY_OPEN": False,
                    "PRINT" : lambda: 1>0,
                    "SELL_CLOSE": False,
                }             
                
                if wait_result["BUY_OPEN"] :     
                    On_BUY(self, B_or_S, symbol, max_volume)                        
                            
                if wait_result["SELL_CLOSE"]:
                    #bors= "BUY" if self.b > price else "SELLL" 
                    On_CLOSE(self, B_or_S, symbol, max_volume)
                if wait_result["PRINT"]:  
                    pass
                
        """
        pass
            
    """
    def case_all(self, wait_result):
        if wait_result["BUY_OPEN"] :     
            self.On_BUY(B_or_S, symbol, max_volume)                        
                    
        if wait_result["SELL_CLOSE"]:
            #bors= "BUY" if self.b > price else "SELLL" 
            self.On_CLOSE(B_or_S, symbol, max_volume)
        if wait_result["PRINT"]:  
            pass       
    """ 
        
    def On_BUY(self, B_or_S, symbol, max_volume):
        #direction="BUY", offset="OPEN"
        if B_or_S == "BUY":
            task_a = self.tm.start_task(make_order_until_all_matched(self.api, symbol= symbol, direction="BUY", offset="OPEN", volume=max_volume))                                          
            #self.On_Open_Buy()     开多仓 
        else:
            task_b = self.tm.start_task(make_order_until_all_matched(self.api, symbol= symbol, direction="SELL", offset="OPEN", volume=max_volume))                             
            #self.On_Open_Sell()    开空仓 
        return task_a if   B_or_S == "BUY" else task_b 
        
    def On_CLOSE(self, B_or_S, symbol, max_volume): 
        """
        #direction="SELL", offset="CLOSE"
        BorS:
            "SELL"   多单持仓 (卖入平仓)
            "BUY"    空单持仓 (买入平仓) 
        """
        if B_or_S == "SELL":    
            """
                "SELL" 原持仓为多单,平仓   "BUY" 原持仓为空单, 平仓
            """
            task_a = self.tm.start_task(make_order_until_all_matched(self.api, symbol= symbol, direction="SELL", offset="CLOSE", volume=max_volume))                                                 
            #self.On_Close_Buy()                          
        else:
            #self.On_Close_Sell()    
            task_b = self.tm.start_task(make_order_until_all_matched(self.api, symbol= symbol, direction="BUY", offset="CLOSE", volume=max_volume))       
   
        return task_a if B_or_S == "SELL" else task_b 
    
    def max_min_ave_ks(self,symbol, m, n = 20):
        """
        Args:
            symbol (str): 指定合约代码.
                 m (int): K线数据周期,以秒为单位。
        Returns:
            Dict:{
                    min: n个数据的最小值
                    max: n个数据的最高值
                    ave: n个数据的平均值
                   }
                   
                   
        使用:
             def task_main(self):
                 quote_a = self.api.get_quote(self.symbol_a)  
                 dictk = self.max_min_ave_ks(self.symbol_a,60 * 60 * 24,20)     
                 while True:
                     wait_result = yield {
                         "BUY_OPEN": lambda: (long_volume == 0 and quote_a["ask_price1"] >= dictk['max']),                           
                           "PRINT" : lambda:  1>0,
                       "SELL_CLOSE": lambda: (long_volume > 0  and quote_a["ask_price1"] <= dictk['min']),
                                         }
                     if wait_result["PRINT"]:            
                         print(......)
                    
                     if wait_result["BUY_OPEN"] :                
                         print("开仓 ", quote_a["ask_price1"] )
                         task_a = self.On_BUY("BUY",self.symbol_a,max_volume)
                         
                     if wait_result["SELL_CLOSE"]:
                         print("平仓 ", quote_a["bid_price1"])
                         task_a = self.On_CLOSE("SELL",self.symbol_a,max_volume)                
                     ........   
        """
        kline_serial_1ks = self.api.get_kline_serial(self.symbol_a, m)
        return  { 'min' : min(kline_serial_1ks.low[-n:]),
                  'max' : max(kline_serial_1ks.high[-n:]),
                  'ave' : sum(kline_serial_1ks.close[-n:])/n,
                 }
    
    def run(self):                    
        self.tm.start_task(self.task_main())
        self.api.run()