shinnytech / tqsdk-python

天勤量化开发包, 期货量化, 实时行情/历史数据/实盘交易
https://doc.shinnytech.com/tqsdk/latest
Apache License 2.0
3.64k stars 650 forks source link

请问怎样实现套利策略?比如rb1901和rb1905价差 #13

Closed iguoke closed 5 years ago

iguoke commented 5 years ago

请问怎样实现套利策略?比如rb1901和rb1905价差 怎样实现同时下单2个合约,并且回测

shinny-chengzhi commented 5 years ago

价差的例子可以参考 https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/t80.py 回测的话在创建 api 实例时传入 TqBacktest 就会进入回测模式 回测的例子可以参考 https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/backtest.py

iguoke commented 5 years ago

价差的例子可以参考 https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/t80.py 回测的话在创建 api 实例时传入 TqBacktest 就会进入回测模式 回测的例子可以参考 https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/backtest.py

可以回测价差策略么?我试了下好像不行,输出成交记录的时候报错,,,

shinny-chengzhi commented 5 years ago

错误是啥呢?贴一下 看看

iguoke commented 5 years ago

错误是啥呢?贴一下 看看

==============================策略代码=======================================

!/usr/bin/env python

-- coding: utf-8 --

author = 'chengzhi'

from tqsdk import TqApi, TqSim, TargetPosTask,TqBacktest from datetime import date

''' 价差回归 当近月-远月的价差大于200时做空近月,做多远月 当价差小于150时平仓 ''' api = TqApi(TqSim(), backtest=TqBacktest(start_dt=date(2018, 11, 1), end_dt=date(2018, 12, 1)))

klines = api.get_kline_serial("SHFE.rb1901", 560, data_length=15) klines2 = api.get_kline_serial("SHFE.rb1905", 560, data_length=15)

创建 rb1810 的目标持仓 task,该 task 负责调整 rb1810 的仓位到指定的目标仓位

target_pos_near = TargetPosTask(api, "SHFE.rb1901")

创建 rb1901 的目标持仓 task,该 task 负责调整 rb1901 的仓位到指定的目标仓位

target_pos_deferred = TargetPosTask(api, "SHFE.rb1905") while True: api.wait_update() if api.is_changing(klines): spread = klines.close[-1] - klines2.close[-1] print("当前价差:", spread) if spread > -400: print("目标持仓: 空近月,多远月")

设置目标持仓为正数表示多头,负数表示空头,0表示空仓

        target_pos_near.set_target_volume(-1)
        target_pos_deferred.set_target_volume(1)
    elif spread < -300:
        print("目标持仓: 空仓")
        target_pos_near.set_target_volume(0)
        target_pos_deferred.set_target_volume(0)

==============================错误信息=========================================

Traceback (most recent call last): File "t80.py", line 22, in api.wait_update() File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 586, in wait_update self._run_once() File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 792, in _run_once raise self.exceptions.pop(0) File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\backtest.py", line 85, in _run await self._send_diff() File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\backtest.py", line 157, in _send_diff await self._fetch_serial(min_serial) File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\backtest.py", line 191, in _fetch_serial raise BacktestFinished() from None tqsdk.exceptions.BacktestFinished: 回测结束 Task was destroyed but it is pending! task: <Task pending coro=<TqApi._windows_patch() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py:826> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000002568565E228>()]> cb=[TqApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<TqApi._notify_watcher() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py:833> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000002568565E108>()]> cb=[TqApi._on_task_done()]> Exception ignored in: <coroutine object TqApi._notify_watcher at 0x000002568574CAC8> Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 833, in _notify_watcher File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 1472, in anext File "C:\ProgramData\Anaconda3\lib\asyncio\queues.py", line 161, in get File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 732, in _call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 677, in call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 469, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<TqApi._connect() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py:850> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000002568565EDC8>()]> cb=[TqApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<TqSim._run() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\sim.py:69> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x0000025686D776D8>()]> cb=[TqApi._on_task_done()]> Exception ignored in: <coroutine object TqApi._connect at 0x000002568574CE48> Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 855, in _connect File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\py35\client.py", line 6, in aexit File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 535, in close File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 400, in wait_for File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 646, in call_later File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 656, in call_at File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 469, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<TqApi._send_handler() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py:868> wait_for=> 模拟交易成交记录 Exception ignored in: <coroutine object TqSim._run at 0x000002568574C9C8> Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\sim.py", line 95, in _run File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\sim.py", line 289, in _report ImportError: sys.meta_path is None, Python is likely shutting down Task was destroyed but it is pending! task: <Task pending coro=<TqSim._md_handler() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\sim.py:99> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x0000025686D77618>()]>> Exception ignored in: <coroutine object TqSim._md_handler at 0x000002568530E948> Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\sim.py", line 99, in _md_handler File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 1472, in anext File "C:\ProgramData\Anaconda3\lib\asyncio\queues.py", line 161, in get File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 732, in _call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 677, in call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 469, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<WebSocketCommonProtocol.transfer_data() running at C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py:674> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000002568565EB28>()]> cb=[<TaskWakeupMethWrapper object at 0x000002568565ECD8>(), _wait.._on_completion() at C:\ProgramData\Anaconda3\lib\asyncio\tasks.py:440]> Task was destroyed but it is pending! task: <Task pending coro=<WebSocketCommonProtocol.keepalive_ping() running at C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py:977> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000002568565EC78>()]>> Task was destroyed but it is pending! task: <Task pending coro=<WebSocketCommonProtocol.close_connection() running at C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py:1019> wait_for=<Task pending coro=<WebSocketCommonProtocol.transfer_data() running at C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py:674> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000002568565EB28>()]> cb=[<TaskWakeupMethWrapper object at 0x000002568565ECD8>(), _wait.._on_completion() at C:\ProgramData\Anaconda3\lib\asyncio\tasks.py:440]>> Exception ignored in: <generator object WebSocketCommonProtocol.close_connection at 0x0000025686CE90C0> Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 1056, in close_connection File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 1080, in wait_for_connection_lost File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 400, in wait_for File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 646, in call_later File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 656, in call_at File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 469, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<TargetPosTask._target_pos_task() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\lib.py:99> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000002568565EB58>()]> cb=[TqApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<TargetPosTask._target_pos_task() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\lib.py:99> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x0000025686D77498>()]> cb=[TqApi._on_task_done()]> Exception ignored in: <coroutine object TargetPosTask._target_pos_task at 0x000002568530E648> Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\lib.py", line 99, in _target_pos_task File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 1472, in anext File "C:\ProgramData\Anaconda3\lib\asyncio\queues.py", line 161, in get File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 732, in _call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 677, in call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 469, in _check_closed RuntimeError: Event loop is closed Exception ignored in: <coroutine object TargetPosTask._target_pos_task at 0x000002568530EF48> Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\lib.py", line 99, in _target_pos_task File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 1472, in anext File "C:\ProgramData\Anaconda3\lib\asyncio\queues.py", line 161, in get File "C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py", line 732, in _call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 677, in call_soon File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 469, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<TqApi._fetch_msg() running at C:\ProgramData\Anaconda3\lib\site-packages\tqsdk\api.py:887> wait_for= cb=[TqApi._on_task_done()]> PS C:\work\st\demo>

shinny-chengzhi commented 5 years ago

回测结束会抛出 BacktestFinished 例外 另外如果不掉用 api.close(), 在程序退出的时候 python 会报一大堆 "Task was destroyed but it is pending" 之类的错误 ,因此正确做法是参照 https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/backtest.py 使用 with closing(api) 或者完全不管也可以,毕竟已经回测完了

iguoke commented 5 years ago

回测结束会抛出 BacktestFinished 例外 另外如果不掉用 api.close(), 在程序退出的时候 python 会报一大堆 "Task was destroyed but it is pending" 之类的错误 ,因此正确做法是参照 https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/backtest.py 使用 with closing(api) 或者完全不管也可以,毕竟已经回测完了 但是,回测结果是没有的,模拟交易成交记录没有,也看不到结果,

iguoke commented 5 years ago

回测结束会抛出 BacktestFinished 例外 另外如果不掉用 api.close(), 在程序退出的时候 python 会报一大堆 "Task was destroyed but it is pending" 之类的错误 ,因此正确做法是参照 https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/backtest.py 使用 with closing(api) 或者完全不管也可以,毕竟已经回测完了 但是,回测结果是没有的,模拟交易成交记录没有,也看不到结果,

额,现在已经可以了 =============一下是通过测试的一个策略==================

!/usr/bin/env python

-- coding: utf-8 --

author = 'liujianping'

from tqsdk import TqApi, TqSim, TargetPosTask from datetime import date from contextlib import closing from tqsdk import TqApi, TqSim, TqBacktest, TargetPosTask import numpy as np from scipy.optimize import leastsq import statsmodels.formula.api as smf import matplotlib.pyplot as plt ''' 价差回归 当近月-远月的价差大于200时做空近月,做多远月 当价差小于150时平仓 ''' api = TqApi(TqSim(), backtest=TqBacktest(start_dt=date(2018, 9, 1), end_dt=date(2018, 12, 27))) klines = api.get_kline_serial("DCE.j1901", 560, data_length=60) klines2 = api.get_kline_serial("DCE.j1905", 560, data_length=60)

创建 rb1810 的目标持仓 task,该 task 负责调整 rb1810 的仓位到指定的目标仓位

target_pos_near = TargetPosTask(api, "DCE.j1901")

创建 rb1901 的目标持仓 task,该 task 负责调整 rb1901 的仓位到指定的目标仓位

target_pos_deferred = TargetPosTask(api, "DCE.j1905") spread=[] with closing(api): while True: api.wait_update() if api.is_changing(klines): spread.append(klines[-1]['close']-klines2[-1]['close']) if len(spread)==30: ma=sum(spread)/30 spread.remove(spread[0])

            if spread[-1]>ma:
                print("目标持仓: 空近月,多远月")
                # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓
                target_pos_near.set_target_volume(-1)
                target_pos_deferred.set_target_volume(1)
            elif spread[-1] < ma:
                print("目标持仓: 空仓")
                target_pos_near.set_target_volume(0)
                target_pos_deferred.set_target_volume(0)