Beispiel #1
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()
Beispiel #2
0
#!/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手")
Beispiel #3
0
#!/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:
Beispiel #4
0
#!/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])
Beispiel #5
0
    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手")
            target_pos.set_target_volume(3)  # 交易
        elif quote["last_price"] < sell_line:  # 低于下轨
Beispiel #6
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"] +
Beispiel #7
0
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()    
Beispiel #8
0
def vwap_table(api: TqApi,
               symbol: str,
               target_pos: int,
               duration: float,
               account: Optional[Union[TqAccount, TqKq, TqSim]] = None):
    """
    返回基于 vwap 策略的计划任务时间表。下单需要配合 TargetPosScheduler 使用。

    调用 vwap_table 函数,根据以下逻辑生成 time_table:

    1. 根据 target_pos - 当前合约的净持仓,得到总的需要调整手数
    2. 请求 symbol 合约的 ``1min`` K 线
    3. 采样取用最近 10 日内,以合约当前行情时间的下一分钟为起点,每日 duration / 60 根 K 线, \
    例如当前合约时间为 14:35:35,那么采样是会使用 14:36:00 开始的分钟线 K 线
    4. 按日期分组,分别计算交易日内,每根 K 线成交量占总成交量的比例
    5. 计算最近 10 日内相同分钟内的成交量占比的算术平均数,将第 1 步得到的总调整手数按照得到的比例分配
    6. 每一分钟,前 58s 以追加价格下单,后 2s 以对价价格下单

    Args:
        api (TqApi): TqApi实例,该task依托于指定api下单/撤单

        symbol (str): 拟下单的合约 symbol, 格式为 交易所代码.合约代码,  例如 "SHFE.cu2201"

        target_pos (int): 目标持仓手数

        duration (int): 算法执行的时长,以秒为单位,必须是 60 的整数倍,时长可以跨非交易时间段,但是不可以跨交易日
        * 设置为 60*10, 可以是 10:10~10:15 + 10:30~10:35

        account (TqAccount/TqKq/TqSim): [可选]指定发送下单指令的账户实例, 多账户模式下,该参数必须指定

    Returns:
        pandas.DataFrame: 本函数返回一个 pandas.DataFrame 实例. 表示一份计划任务时间表。每一行表示一项目标持仓任务,包含以下列:

            + interval: 当前这项任务的持续时间长度,单位为秒
            + target_pos: 当前这项任务的目标持仓
            + price: 当前这项任务的下单价格模式,支持 PASSIVE(排队价),ACTIVE(对价),None(不下单,表示暂停一段时间)

    Example1::

        from tqsdk import TqApi, TargetPosScheduler
        from tqsdk.algorithm import vwap_table

        api = TqApi(auth="信易账户,用户密码")
        quote = api.get_quote("CZCE.MA109")

        # 设置 vwap 任务参数
        time_table = vwap_table(api, "CZCE.MA109", -100, 600)  # 目标持仓 -100 手,600s 内完成
        print(time_table.to_string())

        target_pos_sch = TargetPosScheduler(api, "CZCE.MA109", time_table)
        # 启动循环
        while not target_pos_sch.is_finished():
            api.wait_update()
        api.close()


    """
    account = api._account._check_valid(account)
    if account is None:
        raise Exception(f"多账户模式下, 需要指定账户实例 account")

    TIME_CELL = 60  # 等时长下单的时间单元, 单位: 秒
    HISTORY_DAY_LENGTH = 10  # 使用多少天的历史数据用来计算每个时间单元的下单手数

    if duration % TIME_CELL or duration < 60:
        raise Exception(f"duration {duration} 参数应该为 {TIME_CELL} 的整数倍")

    pos = account.get_position(symbol)
    target_pos = int(target_pos)
    delta_pos = target_pos - pos.pos
    target_volume = abs(delta_pos)  # 总的下单手数
    if target_volume == 0:
        return DataFrame(columns=['interval', 'target_pos', 'price'])

    # 获取 Kline
    klines = api.get_kline_serial(symbol,
                                  TIME_CELL,
                                  data_length=int(10 * 60 * 60 / TIME_CELL *
                                                  HISTORY_DAY_LENGTH))
    klines["time"] = klines.datetime.apply(
        lambda x: datetime.fromtimestamp(x // 1000000000).time())  # k线时间
    klines["date"] = klines.datetime.apply(lambda x: datetime.fromtimestamp(
        _get_trading_day_from_timestamp(x) // 1000000000).date())  # k线交易日

    quote = api.get_quote(symbol)
    # 当前交易日完整的交易时间段
    trading_timestamp = _get_trading_timestamp(quote, quote.datetime)
    trading_timestamp_nano_range = trading_timestamp[
        'night'] + trading_timestamp['day']  # 当前交易日完整的交易时间段
    # 当前时间 行情时间
    current_timestamp_nano = _get_trade_timestamp(quote.datetime, float('nan'))
    if not trading_timestamp_nano_range[0][
            0] <= current_timestamp_nano < trading_timestamp_nano_range[-1][1]:
        raise Exception("当前时间不在指定的交易时间段内")

    current_datetime = datetime.fromtimestamp(current_timestamp_nano //
                                              1000000000)
    # 下一分钟的开始时间
    next_datetime = current_datetime.replace(second=0) + timedelta(minutes=1)
    start_datetime_nano = int(next_datetime.timestamp()) * 1000000000
    r = _rangeset_head(
        _rangeset_slice(trading_timestamp_nano_range, start_datetime_nano),
        int(duration * 1e9))
    if not (r and trading_timestamp_nano_range[0][0] <= r[-1][-1] <
            trading_timestamp_nano_range[-1][1]):
        raise Exception("指定时间段超出当前交易日")

    start_datetime = datetime.fromtimestamp(start_datetime_nano // 1000000000)
    end_datetime = datetime.fromtimestamp((r[-1][-1] - 1) // 1000000000)
    time_slot_start = time(start_datetime.hour,
                           start_datetime.minute)  # 计划交易时段起始时间点
    time_slot_end = time(end_datetime.hour, end_datetime.minute)  # 计划交易时段终点时间点
    if time_slot_end > time_slot_start:  # 判断是否类似 23:00:00 开始, 01:00:00 结束这样跨天的情况
        klines = klines[(klines["time"] >= time_slot_start)
                        & (klines["time"] <= time_slot_end)]
    else:
        klines = klines[(klines["time"] >= time_slot_start) |
                        (klines["time"] <= time_slot_end)]

    # 获取在预设交易时间段内的所有K线, 即时间位于 time_slot_start 到 time_slot_end 之间的数据
    need_date = klines['date'].drop_duplicates()[-HISTORY_DAY_LENGTH:]
    klines = klines[klines['date'].isin(need_date)]

    grouped_datetime = klines.groupby(['date', 'time'])['volume'].sum()
    # 计算每个交易日内的预设交易时间段内的成交量总和(level=0: 表示按第一级索引"data"来分组)后,将每根k线的成交量除以所在交易日内的总成交量,计算其所占比例
    volume_percent = grouped_datetime / grouped_datetime.groupby(level=0).sum()
    predicted_percent = volume_percent.groupby(
        level=1).mean()  # 将历史上相同时间单元的成交量占比使用算数平均计算出预测值

    # 计算每个时间单元的成交量预测值
    time_table = DataFrame(columns=['interval', 'volume', 'price'])
    volume_left = target_volume  # 剩余手数
    percent_left = 1  # 剩余百分比
    for index, value in predicted_percent.items():
        volume = round(target_volume * (value / percent_left))
        volume_left -= volume
        percent_left -= value
        append_time_table = pd.DataFrame([{
            "interval": TIME_CELL - 2,
            "volume": volume,
            "price": "PASSIVE"
        }, {
            "interval": 2,
            "volume": 0,
            "price": "ACTIVE"
        }])
        time_table = pd.concat([time_table, append_time_table],
                               ignore_index=True)

    time_table['volume'] = time_table['volume'].mul(np.sign(delta_pos))
    time_table['target_pos'] = time_table['volume'].cumsum()
    time_table['target_pos'] = time_table['target_pos'].add(pos.pos)
    time_table.drop(columns=['volume'], inplace=True)
    time_table = time_table.astype({
        'target_pos': 'int64',
        'interval': 'float64'
    })
    return time_table