TqSdk

TqSdk 是本人觉得非常好用一套免费自动化交易软件,基于python3,对于有编程经验的人来说上手非常简单。它区别于其它很多自动化交易软件的最好的地方在于,可以用完全同步的方式去开发代码,非常便于调试和梳理逻辑。

对于熟悉Linux的小伙伴来说,TqSdk也非常的节省资源,我有一台上海的阿里云单核512Mb(自己创建了一个2G的虚拟内存),一个月20多元钱,也完全够用。

对自动化交易期权有需求的小伙伴可能不是很适合,因为需要开通专业版,专业版的话收费对于普通用户来说成本相对比较高,建议换其它免费的。

因为我本人用的TqSdk比较多,对将要使用TqSdk用户的小伙伴几点好的建议:

1、不建议使用TqSdk异步的形式去开发代码,因为出问题很难去排查逻辑,即使你去咨询别人的话,别人也很难搞懂你的逻辑。强烈建议使用同步的形式,所有的业务逻辑都写在api.wait_update()之后同步执行。

2、TargetPosTask不建议使用,建议使用最原始的api.insert_order形式。TargetPosTask如果你不看源码,深刻了解里面的运行机制,如果产生了和预期不一致的问题,很难去处理。

3、建议正式自动化交易,买服务器的时候,买阿里云的上海机房,因为TqSdk的行情服务是天勤统一处理的,行情服务器也是部署在阿里云的上海机房,这样我们做自动化交易的时候,能更快的收到行情。

本人用TqSdk封装了一套支持Http请求的开源期货交易软件,easyfut(github地址:https://github.com/hanwanhe/easyfut-python),感兴趣的大家看下,里面不涉及任何的异步代码,逻辑简单,仅供参考,本人不对该软件的正确性做任何担保。

easyfut仅供参考,因使用easyfut实盘造成的任何问题,本人不承担任何责任。

easyfut基本实现原理参考如下:


import time
from multiprocessing import Process,Manager,Queue
from tqsdk import TqApi, TqAuth, TqKq, TqSim, TqAccount
import tornado.ioloop
import tornado.web
import json
import math

#TqSdk账号,需要改成自己的
TQ_USER = 'xxx'
#TqSdk密码,需要改成自己的
TQ_PASSWD = 'xxx'

#下市价单
def my_market_order(api, quote, direction, offset, volume):
  limit_price = None
  if('SHFE' in quote['instrument_id']):
    if(direction == "SELL"):
      limit_price = quote['lower_limit']
    if(direction == "BUY"):
      limit_price = quote['upper_limit']
  if(offset == 'CLOSE' and 'SHFE' in quote['instrument_id']):
    offset = 'CLOSETODAY'
  order = api.insert_order(symbol=quote['instrument_id'], direction=direction, offset=offset, volume=volume, limit_price=limit_price)
  while order.status != "FINISHED":
    api.wait_update()
  return order.trade_price

#处理账户信息请求
class AccountHandler(tornado.web.RequestHandler):
    def initialize(self, share_dict, order_queue):
        #获取引用
        self.share_dict = share_dict
        self.order_queue = order_queue

    def get(self):
        self.finish(self.share_dict['account'])

#处理委托单信息请求
class OrderHandler(tornado.web.RequestHandler):
    def initialize(self, share_dict, order_queue):
        #获取引用
        self.share_dict = share_dict
        self.order_queue = order_queue

    #下单,这里写死了内容,只是演示实现原理
    def post(self):
        #要下单的信息写入消息队列
        self.order_queue.put({'quote':"SHFE.rb2309"})
        self.finish('suc')

    #获取全部委托单信息
    def get(self):
        self.finish(self.share_dict['orders'])

#抽取变量中的kv
def extract_kv(tqsdk_variable):
    kv = {}
    it = iter(tqsdk_variable)
    while True:
        try:
            k = next(it)
            if (
                    isinstance(tqsdk_variable[k], str) or
                    isinstance(tqsdk_variable[k], float) or
                    isinstance(tqsdk_variable[k], int) or
                    isinstance(tqsdk_variable[k], list) or
                    isinstance(tqsdk_variable[k], bool) or 
                    isinstance(tqsdk_variable[k], objs.TradingTime)
            ):
                if(isinstance(tqsdk_variable[k], float)):
                    if(math.isnan(tqsdk_variable[k]) == True):
                        kv[k] = 0.0
                    else:
                        kv[k] = round(tqsdk_variable[k]*100)/100
                else:
                    kv[k] = tqsdk_variable[k]
        except StopIteration:
            break
    return kv

#Tqsdk子进程
class Tqsdk(Process):
    def __init__(self, share_dict, order_queue):
        Process.__init__(self)
        #获取引用
        self.share_dict = share_dict
        self.order_queue = order_queue
        #初始化共享变量
        share_dict['account'] = {}
        share_dict['orders'] = {}


    def run(self):
        #连接tqsdk
        api = TqApi(TqKq(), auth=TqAuth(TQ_USER, TQ_PASSWD))
        #获取账号引用
        account = api.get_account()
        #获取委托引用
        orders = api.get_order()
        #账户信息同步到共享变量
        self.share_dict['account'] = extract_kv(account)
        #委托单信息同步到共享变量
        my_orderes = {}
        for order_id in orders:
            my_orderes[order_id] = extract_kv(orders[order_id])
        self.share_dict['orders'] = my_orderes
        while True:
            #等待数据更新
            api.wait_update(int(time.time())+3)
            #判断消息队列中是否有下单请求,有的话,直接下单
            if(self.order_queue.empty() == False):
                #获取队列信息
                order = self.order_queue.get()
                #下单,这里直接写死了开仓等信息,只是演示实现原理
                my_market_order(api, api.get_quote(order['quote']), "BUY", "OPEN", 1)
            #委托单信息同步到共享变量
            my_orderes = {}
            for order_id in orders:
                my_orderes[order_id] = extract_kv(orders[order_id])
            #账户信息同步到共享变量
            self.share_dict['orders'] = my_orderes
            self.share_dict['account'] = extract_kv(account)

#webserver子进程
class Webserver(Process):
    def __init__(self, share_dict, order_queue):
        Process.__init__(self)
        #获取引用
        self.share_dict = share_dict
        self.order_queue = order_queue

    def run(self):
        #创建app
        app = tornado.web.Application([
            (r"/account", AccountHandler, {'share_dict':self.share_dict, 'order_queue' : self.order_queue}),
            (r"/order", OrderHandler, {'share_dict':self.share_dict, 'order_queue' : self.order_queue}),
        ])
        #监听8888端口
        app.listen(8888)
        #服务启动
        tornado.ioloop.IOLoop.current().start()

if __name__=="__main__":
    #多进程全局共享变量
    manager = Manager()
    share_dict = manager.dict()
    #多进程消息队列
    order_queue = Queue()
    #启动webserver子进程
    p_webserver=Webserver(share_dict, order_queue)
    p_webserver.start()
    #启动Tqsdk子进程
    p_tqsdk=Tqsdk(share_dict, order_queue)
    p_tqsdk.start()
    #父进程等待子进程完成
    p_webserver.join()
    p_tqsdk.join()

本站合作开户:A类大型期货公司,客户经理直开,加1分,有交返。联系微信: ITF-0T ,备注:开户。 支持企业开户,企业开户限时奖励中...