Ejemplo n.º 1
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(AtrRsiStrategy, self).__init__(ctaEngine, setting)

        # 创建K线合成器对象
        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()
Ejemplo n.º 2
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(BollChannelStrategy01, self).__init__(ctaEngine, setting)

        self.bm = BarGenerator(self.onBar, 15, self.on5minBar)  # 创建K线合成器对象
        self.am = ArrayManager()
        self.entryPriceList = []
        self.orderList = []
Ejemplo n.º 3
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(BollingerBotStrategy01, self).__init__(ctaEngine, setting)

        self.bm = BarGenerator(self.onBar, 5, self.onFiveBar)
        self.am = ArrayManager(30)
        self.orderList = []
        self.entryPriceList = []
Ejemplo n.º 4
0
    def __init__(self):
        """Constructor"""
        super(MaSignal, self).__init__()

        self.fastWindow = 5
        self.slowWindow = 20

        self.bg = BarGenerator(self.onBar, 5, self.onFiveBar)
        self.am = ArrayManager()
Ejemplo n.º 5
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(AvgBreakStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 15, self.onMyBar)  # 创建K线合成器对象
        self.am = ArrayManager(size=100)

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []
Ejemplo n.º 6
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(MacdMaStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 5, self.onFiveBar)  # 创建K线合成器对象
        self.am = ArrayManager()

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []
Ejemplo n.º 7
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(DeepLSTMStrategy2016, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 30, self.onFiveBar)  # 创建K线合成器对象
        self.am = ArrayManager(size=200)

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []
Ejemplo n.º 8
0
    def __init__(self):
        """Constructor"""
        super(CciSignal, self).__init__()

        self.cciWindow = 30
        self.cciLevel = 10
        self.cciLong = self.cciLevel
        self.cciShort = -self.cciLevel

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()
Ejemplo n.º 9
0
    def __init__(self):
        """Constructor"""
        super(RsiSignal, self).__init__()

        self.rsiWindow = 14
        self.rsiLevel = 20
        self.rsiLong = 50 + self.rsiLevel
        self.rsiShort = 50 - self.rsiLevel

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()
Ejemplo n.º 10
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(MultiTimeframeStrategy, self).__init__(ctaEngine, setting)

        self.rsiLong = 50 + self.rsiSignal
        self.rsiShort = 50 - self.rsiSignal

        # 创建K线合成器对象
        self.bg5 = BarGenerator(self.onBar, 5, self.on5MinBar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar)
        self.am15 = ArrayManager()
Ejemplo n.º 11
0
class MaSignal(CtaSignal):
    """双均线信号"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        super(MaSignal, self).__init__()

        self.fastWindow = 5
        self.slowWindow = 20

        self.bg = BarGenerator(self.onBar, 5, self.onFiveBar)
        self.am = ArrayManager()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """Tick更新"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """K线更新"""
        self.bg.updateBar(bar)

    #----------------------------------------------------------------------
    def onFiveBar(self, bar):
        """5分钟K线更新"""
        self.am.updateBar(bar)

        if not self.am.inited:
            self.setSignalPos(0)

        fastMa = self.am.sma(self.fastWindow)
        slowMa = self.am.sma(self.slowWindow)

        if fastMa > slowMa:
            self.setSignalPos(1)
        elif fastMa < slowMa:
            self.setSignalPos(-1)
        else:
            self.setSignalPos(0)
Ejemplo n.º 12
0
class CciSignal(CtaSignal):
    """CCI信号"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        super(CciSignal, self).__init__()

        self.cciWindow = 30
        self.cciLevel = 10
        self.cciLong = self.cciLevel
        self.cciShort = -self.cciLevel

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """Tick更新"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """K线更新"""
        self.am.updateBar(bar)

        if not self.am.inited:
            self.setSignalPos(0)

        cciValue = self.am.cci(self.cciWindow)

        if cciValue >= self.cciLong:
            self.setSignalPos(1)
        elif cciValue <= self.cciShort:
            self.setSignalPos(-1)
        else:
            self.setSignalPos(0)
Ejemplo n.º 13
0
class RsiSignal(CtaSignal):
    """RSI信号"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        super(RsiSignal, self).__init__()

        self.rsiWindow = 14
        self.rsiLevel = 20
        self.rsiLong = 50 + self.rsiLevel
        self.rsiShort = 50 - self.rsiLevel

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """Tick更新"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """K线更新"""
        self.am.updateBar(bar)

        if not self.am.inited:
            self.setSignalPos(0)

        rsiValue = self.am.rsi(self.rsiWindow)

        if rsiValue >= self.rsiLong:
            self.setSignalPos(1)
        elif rsiValue <= self.rsiShort:
            self.setSignalPos(-1)
        else:
            self.setSignalPos(0)
Ejemplo n.º 14
0
 def __init__(self, ctaEngine, setting):
     """Constructor"""
     super(BollChannelStrategy, self).__init__(ctaEngine, setting)
     
     self.bg = BarGenerator(self.onBar, 15, self.onXminBar)        # 创建K线合成器对象
     self.am = ArrayManager()
Ejemplo n.º 15
0
class BollChannelStrategy(CtaTemplate):
    """基于布林通道的交易策略"""
    className = 'BollChannelStrategy'
    author = u'用Python的交易员'

    # 策略参数
    bollWindow = 18                     # 布林通道窗口数
    bollDev = 3.4                       # 布林通道的偏差
    cciWindow = 10                      # CCI窗口数
    atrWindow = 30                      # ATR窗口数
    slMultiplier = 5.2                  # 计算止损距离的乘数
    initDays = 10                       # 初始化数据所用的天数
    fixedSize = 1                       # 每次交易的数量

    # 策略变量
    bollUp = 0                          # 布林通道上轨
    bollDown = 0                        # 布林通道下轨
    cciValue = 0                        # CCI指标数值
    atrValue = 0                        # ATR指标数值
    
    intraTradeHigh = 0                  # 持仓期内的最高点
    intraTradeLow = 0                   # 持仓期内的最低点
    longStop = 0                        # 多头止损
    shortStop = 0                       # 空头止损

    # 参数列表,保存了参数的名称
    paramList = ['name',
                 'className',
                 'author',
                 'vtSymbol',
                 'bollWindow',
                 'bollDev',
                 'cciWindow',
                 'atrWindow',
                 'slMultiplier',
                 'initDays',
                 'fixedSize']    

    # 变量列表,保存了变量的名称
    varList = ['inited',
               'trading',
               'pos',
               'bollUp',
               'bollDown',
               'cciValue',
               'atrValue',
               'intraTradeHigh',
               'intraTradeLow',
               'longStop',
               'shortStop']  
    
    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos',
                'intraTradeHigh',
                'intraTradeLow']    

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(BollChannelStrategy, self).__init__(ctaEngine, setting)
        
        self.bg = BarGenerator(self.onBar, 15, self.onXminBar)        # 创建K线合成器对象
        self.am = ArrayManager()
            
    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' %self.name)
        
        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' %self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' %self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)""" 
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bg.updateBar(bar)
    
    #----------------------------------------------------------------------
    def onXminBar(self, bar):
        """收到X分钟K线"""
        # 全撤之前发出的委托
        self.cancelAll()
    
        # 保存K线数据
        am = self.am
        
        am.updateBar(bar)
        
        if not am.inited:
            return
        
        # 计算指标数值
        self.bollUp, self.bollDown = am.boll(self.bollWindow, self.bollDev)
        self.cciValue = am.cci(self.cciWindow)
        self.atrValue = am.atr(self.atrWindow)
        
        # 判断是否要进行交易
    
        # 当前无仓位,发送开仓委托
        if self.pos == 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = bar.low            
            
            if self.cciValue > 0:
                self.buy(self.bollUp, self.fixedSize, True)
                
            elif self.cciValue < 0:
                self.short(self.bollDown, self.fixedSize, True)
    
        # 持有多头仓位
        elif self.pos > 0:
            self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
            self.intraTradeLow = bar.low
            self.longStop = self.intraTradeHigh - self.atrValue * self.slMultiplier
            
            self.sell(self.longStop, abs(self.pos), True)
    
        # 持有空头仓位
        elif self.pos < 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = min(self.intraTradeLow, bar.low)
            self.shortStop = self.intraTradeLow + self.atrValue * self.slMultiplier
            
            self.cover(self.shortStop, abs(self.pos), True)
            
        # 同步数据到数据库
        self.saveSyncData()        
    
        # 发出状态更新事件
        self.putEvent()        

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        """成交推送"""
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 16
0
class BasicLSTMStrategy(CtaTemplate):
    """基于Adxr的交易策略"""
    className = 'BasicLSTMStrategy'
    author = u'用Python的交易员'

    barDbName = DAILY_DB_NAME


    # 策略参数
    trailingPrcnt = 0.8     # 移动止损
    initDays =  350          # 初始化数据所用的天数
    fixedSize = 1           # 每次交易的数量
    # 策略变量

    intraTradeHigh = 0                  # 持仓期内的最高点
    intraTradeLow = 0                   # 持仓期内的最低点

    model_classifier = None

    flag  = 0
    targetPos = 0

    buyOrderIDList = []                 # OCO委托买入开仓的委托号
    shortOrderIDList = []               # OCO委托卖出开仓的委托号
    orderList = []                      # 保存委托代码的列表

    # 参数列表,保存了参数的名称
    paramList = ['name',
                 'className',
                 'author',
                 'vtSymbol']

    # 变量列表,保存了变量的名称
    varList = ['inited',
               'trading',
               'pos',
               'flag',
               'targetPos'
               ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos',
                'intraTradeHigh',
                'intraTradeLow']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(BasicLSTMStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 30, self.onFiveBar)  # 创建K线合成器对象

        self.am = ArrayManager(size=200)

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' %self.name)



        tmp = fix_data(u'data/AG88.csv')

        # targets 1d 数据合成
        tmp_1d = High_2_Low(tmp, '1d')
        rolling = 88
        targets = tmp_1d
        targets['returns'] = targets['close'].shift(-2) / targets['close'] - 1.0
        targets['upper_boundary'] = targets.returns.rolling(rolling).mean() + 0.5 * targets.returns.rolling(
            rolling).std()
        targets['lower_boundary'] = targets.returns.rolling(rolling).mean() - 0.5 * targets.returns.rolling(
            rolling).std()
        targets.dropna(inplace=True)
        targets['labels'] = 1
        targets.loc[targets['returns'] >= targets['upper_boundary'], 'labels'] = 2
        targets.loc[targets['returns'] <= targets['lower_boundary'], 'labels'] = 0

        # factors 1d 数据合成
        tmp_1d = High_2_Low(tmp, '1d')
        Index = tmp_1d.index
        High = tmp_1d.high.values
        Low = tmp_1d.low.values
        Close = tmp_1d.close.values
        Open = tmp_1d.open.values
        Volume = tmp_1d.volume.values
        factors = get_factors(Index, Open, Close, High, Low, Volume, rolling=26, drop=True)
        factors = factors.loc[:targets.index[-1]]
        tmp_factors_1 = factors.iloc[:12]
        targets = targets.loc[tmp_factors_1.index[-1]:]
        gather_list = np.arange(factors.shape[0])[11:]
        # #### 转换数据
        inputs = np.array(factors).reshape(-1, 1, factors.shape[1])
        targets = dense_to_one_hot(targets['labels'])
        targets = np.expand_dims(targets, axis=1)

        op1 = Classifier_PonderDNC_BasicLSTM_L3(
            inputs=inputs,
            targets=targets,
            gather_list=gather_list,
            hidden_size=50,
            memory_size=50,
            pondering_coefficient=1e-1,
            learning_rate=1e-4)

        op1.restore_trainable_variables("/QuantPython/RqAlphaMod/Model_Saver/ResidualPonderDNC_4.ckpt")
        self.model_classifier = op1

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onMyBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' %self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' %self.name)
        self.putEvent()



    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bg.updateBar(bar)
        if self.targetPos > 0:
            if self.pos == 0:
                orderID = self.buy(bar.close + 5, self.fixedSize)
                self.orderList.extend(orderID)
            if self.pos < 0:
                orderID = self.cover(bar.close + 5, abs(self.pos))
                self.orderList.extend(orderID)
                time.sleep(3)
                orderID = self.buy(bar.close + 5, self.fixedSize)
                self.orderList.extend(orderID)

        if self.targetPos < 0:
            if self.pos == 0:
                orderID = self.short(bar.close - 5, self.fixedSize)
                self.orderList.extend(orderID)
            if self.pos > 0:
                orderID = self.sell(bar.close - 5, abs(self.pos))
                self.orderList.extend(orderID)
                time.sleep(3)
                orderID = self.short(bar.close - 5, self.fixedSize)
                self.orderList.extend(orderID)

        if self.targetPos == 0:
            if self.pos > 0:
                orderID = self.sell(bar.close - 5, abs(self.pos))
                self.orderList.extend(orderID)
            if self.pos < 0:
                orderID = self.cover(bar.close + 5, abs(self.pos))
                self.orderList.extend(orderID)
        self.putEvent()
    
    #---------------------------------------------------------------------
    def onFiveBar(self, bar):
        """收到5分钟K线"""

     # 同步数据到数据库
        self.saveSyncData()

        # 发出状态更新事件
        self.putEvent()



    #----------------------------------------------------------------------
    def onMyBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        # 保存K线数据
        am = self.am
        am.updateBar(bar)

        if not am.inited:
            return


        tmp_factors =get_factors(
            pd.to_datetime(am.datetimeArray),
            am.openArray,
            am.closeArray,
            am.highArray,
            am.lowArray,
            am.volumeArray,
            rolling=26,
            drop = True)
        inputs = np.expand_dims(np.array(tmp_factors), axis=1)

        # 模型预测
        probability, classification = self.model_classifier.pred(inputs)
        flag = classification[-1][0]
        self.flag = flag

        #沽空
        if flag == 0:
            self.targetPos = -self.fixedSize
        #沽多
        if flag == 2:
            self.targetPos = self.fixedSize
        #震荡
        if flag == 1:
            self.targetPos = 0
        # 发出状态更新事件
        self.putEvent()

   #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass



    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # if self.pos != 0:
        #     # 多头开仓成交后,撤消空头委托
        #     if self.pos > 0:
        #         for shortOrderID in self.shortOrderIDList:
        #             self.cancelOrder(shortOrderID)
        #     # 反之同样
        #     elif self.pos < 0:
        #         for buyOrderID in self.buyOrderIDList:
        #             self.cancelOrder(buyOrderID)
        #
        #     # 移除委托号
        #     for orderID in (self.buyOrderIDList + self.shortOrderIDList):
        #         if orderID in self.orderList:
        #             self.orderList.remove(orderID)

        # 发出状态更新事件
        self.putEvent()


    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 17
0
class AdxrStrategy(CtaTemplate):
    """基于Adxr的交易策略"""
    className = 'AdxrStrategy'
    author = u'用Python的交易员'

    # 策略参数
    trailingPrcnt = 0.8  # 移动止损
    initDays = 20  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量
    aPeriod = 8  # 窗口数
    targetPos = 0

    # 策略变量

    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点

    fastMa = 0
    middleMa = 0
    slowMa = 0
    adxr = 0
    pdi = 0
    mdi = 0

    buyOrderIDList = []  # OCO委托买入开仓的委托号
    shortOrderIDList = []  # OCO委托卖出开仓的委托号
    orderList = []  # 保存委托代码的列表

    # 参数列表,保存了参数的名称
    paramList = ['name', 'className', 'author', 'vtSymbol', 'aPeriod']

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'targetPos', 'fastMa', 'middleMa',
        'slowMa', 'adxr', 'pdi', 'mdi'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(AdxrStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 15, self.onFifteenBar)  # 创建K线合成器对象
        self.am = ArrayManager()

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bg.updateBar(bar)

        for orderID in self.orderList:
            self.cancelOrder(orderID)
            self.orderList = []

        if self.targetPos > 0:
            if self.pos == 0:
                orderID = self.buy(bar.close + 5, self.fixedSize)
                self.orderList.extend(orderID)
            if self.pos < 0:
                orderID = self.cover(bar.close + 5, abs(self.pos))
                self.orderList.extend(orderID)
                time.sleep(3)
                orderID = self.buy(bar.close + 5, self.fixedSize)
                self.orderList.extend(orderID)

        if self.targetPos < 0:
            if self.pos == 0:
                orderID = self.short(bar.close - 5, self.fixedSize)
                self.orderList.extend(orderID)
            if self.pos > 0:
                orderID = self.sell(bar.close - 5, abs(self.pos))
                self.orderList.extend(orderID)
                time.sleep(3)
                orderID = self.short(bar.close - 5, self.fixedSize)
                self.orderList.extend(orderID)

        self.putEvent()

    #----------------------------------------------------------------------
    def onFifteenBar(self, bar):
        """收到15分钟K线"""
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        for orderID in self.orderList:
            self.cancelOrder(orderID)
        self.orderList = []

        # 保存K线数据
        am = self.am
        am.updateBar(bar)

        if not am.inited:
            return

        # 计算指标数值

        std0 = np.std(am.close[-self.aPeriod - 1:-1])
        std1 = np.std(am.close[-self.aPeriod:])

        if std1 == 0:
            return

        volatility = (std1 - std0) / std1

        if volatility < 0.1:
            volatility = 0.1

        period = int(self.aPeriod * (1 + volatility))

        fast_ma = talib.MA(am.close, period)
        middle_ma = talib.MA(am.close, 2 * period)
        slow_ma = talib.MA(am.close, 3 * period)

        adxr = talib.ADXR(am.high, am.low, am.close, self.aPeriod)
        pdi = talib.PLUS_DI(am.high, am.low, am.close, self.aPeriod)
        mdi = talib.MINUS_DI(am.high, am.low, am.close, self.aPeriod)

        self.fastMa = fast_ma[-1]
        self.middleMa = middle_ma[-1]
        self.slowMa = slow_ma[-1]
        self.adxr = adxr[-1]
        self.pdi = pdi[-1]
        self.mdi = mdi[-1]

        # 判断是否要进行交易
        # 多头
        if self.adxr > 30 and self.pdi > self.mdi and self.fastMa > self.middleMa > self.slowMa:
            self.targetPos = self.fixedSize

        # 空头
        if self.adxr > 30 and self.mdi > self.pdi and self.fastMa < self.middleMa < self.slowMa:
            self.targetPos = -self.fixedSize

        # 同步数据到数据库
        self.saveSyncData()

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # if self.pos != 0:
        #     # 多头开仓成交后,撤消空头委托
        #     if self.pos > 0:
        #         for shortOrderID in self.shortOrderIDList:
        #             self.cancelOrder(shortOrderID)
        #     # 反之同样
        #     elif self.pos < 0:
        #         for buyOrderID in self.buyOrderIDList:
        #             self.cancelOrder(buyOrderID)
        #
        #     # 移除委托号
        #     for orderID in (self.buyOrderIDList + self.shortOrderIDList):
        #         if orderID in self.orderList:
        #             self.orderList.remove(orderID)

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 18
0
class BollChannelStrategy01(CtaTemplate):
    """基于布林通道的交易策略"""
    className = 'BollChannelStrategy01'
    author = 'Y.Raul'

    # 策略参数
    bollWindow = 18  # 布林通道窗口数
    bollDev = 5  # 布林通道的偏差
    cciWindow = 10  # CCI窗口数
    atrWindow = 30  # ATR窗口数
    slMultiplier = 5  # 计算止损距离的乘数
    initDays = 30  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 策略变量
    bollUp = 0  # 布林通道上轨
    bollDown = 0  # 布林通道下轨
    bollMid = 0
    cciValue = 0  # CCI指标数值
    atrValue = 0  # ATR指标数值
    filterTime = True  #是否过滤9点开盘后头五分钟,15点收盘前五分钟

    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点
    longStop = 0  # 多头止损
    shortStop = 0  # 空头止损
    avgEntryPrice = 0  #平均入场价
    avgExitPrice = 0  #平均出场价
    buySig = False
    shortSig = False
    exitOnLossStop = 2
    miniDiff = 1

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'bollWindow', 'bollDev',
        'cciWindow', 'atrWindow', 'slMultiplier', 'initDays', 'fixedSize'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'bollUp', 'bollDown', 'cciValue',
        'atrValue', 'intraTradeHigh', 'intraTradeLow', 'longStop', 'shortStop'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(BollChannelStrategy01, self).__init__(ctaEngine, setting)

        self.bm = BarGenerator(self.onBar, 15, self.on5minBar)  # 创建K线合成器对象
        self.am = ArrayManager()
        self.entryPriceList = []
        self.orderList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog('%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog('%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog('%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bm.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):

        self.bm.updateBar(bar)
        if not self.trading:
            # 记录log
            # log = "-----" * 10 + "\n@onBar\n" + \
            #         "trading: {0}\n".format(self.trading)+\
            #       "bar.datetime: {0}; pos: {1} \n".format(bar.datetime, self.pos) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig)
            # self.writeCtaLog(log)
            # print(log)
            self.buySig = False
            self.shortSig = False
            return

        # 检查开仓信号
        if self.buySig:
            res = self.buy(self.bollUp, self.fixedSize)
            self.orderList.extend(res)

            # 记录log
            # log = "-----" * 10 + "\n@onBar\n" + \
            #       "bar.datetime: {0}; pos: {1} \n".format(bar.datetime, self.pos) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig)
            # self.writeCtaLog(log)
            #
            # log = "\n Trading: {0}\n".format(self.trading) + \
            #       "{0} Buy : bar.close: {1};\n".format(bar.datetime, bar.close) + \
            #       " entryUp:{0}; cci:{1};\n".format(self.bollUp, self.cciValue)
            # self.writeCtaLog(log)
            self.buySig = False
            # print(log)

        if self.shortSig:
            res = self.short(self.bollDown, self.fixedSize)
            self.orderList.extend(res)

            # 记录log
            # log = "-----" * 10 + "\n@onBar\n" + \
            #       "bar.datetime: {0}; pos: {1} \n".format(bar.datetime, self.pos) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig)
            # self.writeCtaLog(log)
            #
            # log = "\n Trading: {0}\n".format(self.trading) + \
            #       "{0} Short : bar.close: {1};\n".format(bar.datetime, bar.close) + \
            #       " entryDown:{0}; cci:{1};\n".format(self.bollDown, self.cciValue)
            # self.writeCtaLog(log)
            self.shortSig = False
            # print(log)

        self.putEvent()

    #----------------------------------------------------------------------
    def on5minBar(self, bar):
        """收到X分钟K线"""
        # 全撤之前发出的委托
        self.cancelAll()

        # 保存K线数据
        am = self.am

        am.updateBar(bar)

        if not am.inited:
            return

        # 计算指标数值
        self.bollUp, self.bollDown, self.bollMid = am.boll(
            self.bollWindow, self.bollDev)
        self.cciValue = am.cci(self.cciWindow)

        atrArray = am.atr(self.atrWindow, array=True)
        self.atrValue = atrArray[-1]
        self.atrMa = atrArray[-self.atrWindow:].mean()
        # 判断是否要进行交易

        # 当前无仓位,发送开仓委托,限价单
        if self.pos == 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = bar.low
            self.entryPriceList = []
            self.orderList = []
            self.avgEntryPrice = []
            import datetime
            timeWindow = True
            if self.filterTime:
                timeWindow = bar.datetime.time() > datetime.time(
                    9) and bar.datetime.time() < datetime.time(14, 55)

            if timeWindow:
                if self.cciValue > 0 and self.atrValue > self.atrMa:
                    # if self.cciValue > 0 :
                    self.buySig = True

                elif self.cciValue < 0 and self.atrValue < self.atrMa:
                    # elif self.cciValue < 0:
                    self.shortSig = True

            # 记录log
            # log = "-----" * 10 + "\n@on5minBar\n" + \
            #     "timeWidow: {0}\n".format(timeWindow) +\
            #     "bar.datetime: {0}; pos: {1} ; close: {2}\n".format(bar.datetime, self.pos, bar.close) + \
            #     "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig) + \
            #     "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #     "intraTradeLow: {0}\n".format(self.intraTradeLow)
            # self.writeCtaLog(log)
            # print(log)

        # 当前有仓位,以本地停止单止损
        # 持有多头仓位
        elif self.pos > 0:
            self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
            self.intraTradeLow = bar.low
            self.longStop = self.intraTradeHigh - self.atrValue * self.slMultiplier

            # if bar.close < self.stopExit:
            #     #固定止损
            #     self.sell(bar.close, abs(self.pos), True)
            # else:
            #     #跟随止损
            #     self.sell(self.longStop, abs(self.pos), True)
            self.sell(self.longStop, abs(self.pos), True)

            # 记录log
            # log = "-----" * 10 + "\n@on5minBar\n" + \
            #       "bar.datetime: {0}; pos: {1} ; close: {2}\n".format(bar.datetime, self.pos, bar.close) + \
            #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #       "intraTradeLow: {0}\n".format(self.intraTradeLow)
            # "avgEntryPrice: {0}\n".format(self.avgEntryPrice) + \
            # "longStop: {0}\n".format(self.longStop) + \
            # "stopExit:{0}\n".format(self.stopExit)
            #
            # self.writeCtaLog(log)
            # print(log)

        # 持有空头仓位
        elif self.pos < 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = min(self.intraTradeLow, bar.low)
            self.shortStop = self.intraTradeLow + self.atrValue * self.slMultiplier

            # if bar.close > self.stopExit:
            #     #固定止损
            #     self.cover(bar.close, abs(self.pos), True)
            # else:
            #     #跟随止损
            #     self.cover(self.shortStop, abs(self.pos), True)
            self.cover(self.shortStop, abs(self.pos), True)

            # 记录log
            # log = "-----" * 10 + "\n@on5minBar\n" + \
            #       "bar.datetime: {0}; pos: {1} ; close: {2}\n".format(bar.datetime, self.pos, bar.close) + \
            #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #       "intraTradeLow: {0}\n".format(self.intraTradeLow) +\
            #       "avgEntryPrice: {0}\n".format(self.avgEntryPrice) + \
            #       "shortStop: {0}\n".format(self.longStop) + \
            #       "stopExit:{0}\n".format(self.stopExit)
            # self.writeCtaLog(log)
            # print(log)
            # 同步数据到数据库
        self.saveSyncData()
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        '''
        处理order更新
        :param order:
        :return:
        '''
        # 记录log
        # log = "-----" * 10 + "\n@onOrder\n" + \
        #       "orderTime: {0}; pos: {1} \n".format(order.orderTime, order.totalVolume) + \
        #       "status {0}; vtOrderID: {1}\n".format(order.status, order.vtOrderID)+ \
        #       "direction:{0}\n".format(order.direction)
        # self.writeCtaLog(log)
        # print(log)

        # 对于开仓,记录相关价格
        if order.direction == DIRECTION_LONG and order.offset == OFFSET_OPEN:
            if order.totalVolume == order.tradedVolume:
                # 更新入场价列表,更新平均入场价
                self.entryPriceList.append(order.price)
                self.avgEntryPrice = sum(self.entryPriceList) / len(
                    self.entryPriceList)
                self.stopExit = round(self.avgEntryPrice *
                                      (100 - self.exitOnLossStop) /
                                      100)  # 固定止损价

        elif order.direction == DIRECTION_SHORT and order.offset == OFFSET_OPEN:
            # 更新入场价列表,更新平均入场价
            if order.totalVolume == order.tradedVolume:
                # 更新入场价列表,更新平均入场价
                self.entryPriceList.append(order.price)
                self.avgEntryPrice = sum(self.entryPriceList) / len(
                    self.entryPriceList)
                self.stopExit = round(self.avgEntryPrice *
                                      (1 + self.exitOnLossStop) / 100)  # 固定止损价

        self.putEvent()

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 19
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(TurtleTradingStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()
Ejemplo n.º 20
0
class KkStrategy(CtaTemplate):
    """基于King Keltner通道的交易策略"""
    className = 'KkStrategy'
    author = u'用Python的交易员'

    # 策略参数
    kkLength = 11  # 计算通道中值的窗口数
    kkDev = 1.6  # 计算通道宽度的偏差
    trailingPrcnt = 0.8  # 移动止损
    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 策略变量
    kkUp = 0  # KK通道上轨
    kkDown = 0  # KK通道下轨
    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点

    buyOrderIDList = []  # OCO委托买入开仓的委托号
    shortOrderIDList = []  # OCO委托卖出开仓的委托号
    orderList = []  # 保存委托代码的列表

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'kkLength', 'kkDev'
    ]

    # 变量列表,保存了变量的名称
    varList = ['inited', 'trading', 'pos', 'kkUp', 'kkDown']

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(KkStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 5, self.onFiveBar)  # 创建K线合成器对象
        self.am = ArrayManager()

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bg.updateBar(bar)

    #----------------------------------------------------------------------
    def onFiveBar(self, bar):
        """收到5分钟K线"""
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        for orderID in self.orderList:
            self.cancelOrder(orderID)
        self.orderList = []

        # 保存K线数据
        am = self.am
        am.updateBar(bar)
        if not am.inited:
            return

        # 计算指标数值
        self.kkUp, self.kkDown = am.keltner(self.kkLength, self.kkDev)

        # 判断是否要进行交易

        # 当前无仓位,发送OCO开仓委托
        if self.pos == 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = bar.low
            self.sendOcoOrder(self.kkUp, self.kkDown, self.fixedSize)

        # 持有多头仓位
        elif self.pos > 0:
            self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
            self.intraTradeLow = bar.low

            l = self.sell(self.intraTradeHigh * (1 - self.trailingPrcnt / 100),
                          abs(self.pos), True)
            self.orderList.extend(l)

        # 持有空头仓位
        elif self.pos < 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = min(self.intraTradeLow, bar.low)

            l = self.cover(self.intraTradeLow * (1 + self.trailingPrcnt / 100),
                           abs(self.pos), True)
            self.orderList.extend(l)

        # 同步数据到数据库
        self.saveSyncData()

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        if self.pos != 0:
            # 多头开仓成交后,撤消空头委托
            if self.pos > 0:
                for shortOrderID in self.shortOrderIDList:
                    self.cancelOrder(shortOrderID)
            # 反之同样
            elif self.pos < 0:
                for buyOrderID in self.buyOrderIDList:
                    self.cancelOrder(buyOrderID)

            # 移除委托号
            for orderID in (self.buyOrderIDList + self.shortOrderIDList):
                if orderID in self.orderList:
                    self.orderList.remove(orderID)

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def sendOcoOrder(self, buyPrice, shortPrice, volume):
        """
        发送OCO委托
        
        OCO(One Cancel Other)委托:
        1. 主要用于实现区间突破入场
        2. 包含两个方向相反的停止单
        3. 一个方向的停止单成交后会立即撤消另一个方向的
        """
        # 发送双边的停止单委托,并记录委托号
        self.buyOrderIDList = self.buy(buyPrice, volume, True)
        self.shortOrderIDList = self.short(shortPrice, volume, True)

        # 将委托号记录到列表中
        self.orderList.extend(self.buyOrderIDList)
        self.orderList.extend(self.shortOrderIDList)

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 21
0
class AtrRsiStrategy(CtaTemplate):
    """结合ATR和RSI指标的一个分钟线交易策略"""
    className = 'AtrRsiStrategy'
    author = u'用Python的交易员'

    # 策略参数
    atrLength = 22  # 计算ATR指标的窗口数
    atrMaLength = 10  # 计算ATR均线的窗口数
    rsiLength = 5  # 计算RSI的窗口数
    rsiEntry = 16  # RSI的开仓信号
    trailingPercent = 0.8  # 百分比移动止损
    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 策略变量
    atrValue = 0  # 最新的ATR指标数值
    atrMa = 0  # ATR移动平均的数值
    rsiValue = 0  # RSI指标的数值
    rsiBuy = 0  # RSI买开阈值
    rsiSell = 0  # RSI卖开阈值
    intraTradeHigh = 0  # 移动止损用的持仓期内最高价
    intraTradeLow = 0  # 移动止损用的持仓期内最低价

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'atrLength', 'atrMaLength',
        'rsiLength', 'rsiEntry', 'trailingPercent'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'atrValue', 'atrMa', 'rsiValue', 'rsiBuy',
        'rsiSell'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(AtrRsiStrategy, self).__init__(ctaEngine, setting)

        # 创建K线合成器对象
        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()

        # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建,
        # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险,
        # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读
        # 策略时方便(更多是个编程习惯的选择)

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 初始化RSI入场阈值
        self.rsiBuy = 50 + self.rsiEntry
        self.rsiSell = 50 - self.rsiEntry

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.cancelAll()

        # 保存K线数据
        am = self.am
        am.updateBar(bar)
        if not am.inited:
            return

        # 计算指标数值
        atrArray = am.atr(self.atrLength, array=True)
        self.atrValue = atrArray[-1]
        self.atrMa = atrArray[-self.atrMaLength:].mean()

        self.rsiValue = am.rsi(self.rsiLength)

        # 判断是否要进行交易

        # 当前无仓位
        if self.pos == 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = bar.low

            # ATR数值上穿其移动平均线,说明行情短期内波动加大
            # 即处于趋势的概率较大,适合CTA开仓
            if self.atrValue > self.atrMa:
                # 使用RSI指标的趋势行情时,会在超买超卖区钝化特征,作为开仓信号
                if self.rsiValue > self.rsiBuy:
                    # 这里为了保证成交,选择超价5个整指数点下单
                    self.buy(bar.close + 5, self.fixedSize)

                elif self.rsiValue < self.rsiSell:
                    self.short(bar.close - 5, self.fixedSize)

        # 持有多头仓位
        elif self.pos > 0:
            # 计算多头持有期内的最高价,以及重置最低价
            self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
            self.intraTradeLow = bar.low

            # 计算多头移动止损
            longStop = self.intraTradeHigh * (1 - self.trailingPercent / 100)

            # 发出本地止损委托
            self.sell(longStop, abs(self.pos), stop=True)

        # 持有空头仓位
        elif self.pos < 0:
            self.intraTradeLow = min(self.intraTradeLow, bar.low)
            self.intraTradeHigh = bar.high

            shortStop = self.intraTradeLow * (1 + self.trailingPercent / 100)
            self.cover(shortStop, abs(self.pos), stop=True)

        # 同步数据到数据库
        self.saveSyncData()

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 22
0
class DoubleMaStrategy(CtaTemplate):
    """双指数均线策略Demo"""
    className = 'DoubleMaStrategy'
    author = u'用Python的交易员'

    # 策略参数
    fastWindow = 10  # 快速均线参数
    slowWindow = 60  # 慢速均线参数
    initDays = 10  # 初始化数据所用的天数

    # 策略变量
    fastMa0 = EMPTY_FLOAT  # 当前最新的快速EMA
    fastMa1 = EMPTY_FLOAT  # 上一根的快速EMA

    slowMa0 = EMPTY_FLOAT
    slowMa1 = EMPTY_FLOAT

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'fastWindow', 'slowWindow'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'fastMa0', 'fastMa1', 'slowMa0', 'slowMa1'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(DoubleMaStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()

        # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建,
        # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险,
        # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读
        # 策略时方便(更多是个编程习惯的选择)

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'双EMA演示策略初始化')

        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'双EMA演示策略启动')
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'双EMA演示策略停止')
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        am = self.am
        am.updateBar(bar)
        if not am.inited:
            return

        # 计算快慢均线
        fastMa = am.sma(self.fastWindow, array=True)
        self.fastMa0 = fastMa[-1]
        self.fastMa1 = fastMa[-2]

        slowMa = am.sma(self.slowWindow, array=True)
        self.slowMa0 = slowMa[-1]
        self.slowMa1 = slowMa[-2]

        # 判断买卖
        crossOver = self.fastMa0 > self.slowMa0 and self.fastMa1 < self.slowMa1  # 金叉上穿
        crossBelow = self.fastMa0 < self.slowMa0 and self.fastMa1 > self.slowMa1  # 死叉下穿

        # 金叉和死叉的条件是互斥
        # 所有的委托均以K线收盘价委托(这里有一个实盘中无法成交的风险,考虑添加对模拟市价单类型的支持)
        if crossOver:
            # 如果金叉时手头没有持仓,则直接做多
            if self.pos == 0:
                self.buy(bar.close, 1)
            # 如果有空头持仓,则先平空,再做多
            elif self.pos < 0:
                self.cover(bar.close, 1)
                self.buy(bar.close, 1)
        # 死叉和金叉相反
        elif crossBelow:
            if self.pos == 0:
                self.short(bar.close, 1)
            elif self.pos > 0:
                self.sell(bar.close, 1)
                self.short(bar.close, 1)

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        # 对于无需做细粒度委托控制的策略,可以忽略onOrder
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        """收到成交推送(必须由用户继承实现)"""
        # 对于无需做细粒度委托控制的策略,可以忽略onOrder
        pass

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 23
0
class AvgBreakStrategy(TargetPosTemplate):
    """基于Adxr的交易策略"""
    className = 'AvgBreakStrategy'
    author = u'用Python的交易员'

    # 策略参数
    trailingPrcnt = 0.8  # 移动止损
    initDays = 30  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量
    m1 = 34
    m2 = 2.2
    # 策略变量

    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点

    buyOrderIDList = []  # OCO委托买入开仓的委托号
    shortOrderIDList = []  # OCO委托卖出开仓的委托号
    orderList = []  # 保存委托代码的列表

    # 参数列表,保存了参数的名称
    paramList = ['name', 'className', 'author', 'vtSymbol', 'm1', 'm2']

    # 变量列表,保存了变量的名称
    varList = ['inited', 'trading', 'pos', 'targetPos']

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow']

    # ----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(AvgBreakStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 15, self.onMyBar)  # 创建K线合成器对象
        self.am = ArrayManager(size=100)

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []

    # ----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    # ----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    # ----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    # ----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        TargetPosTemplate.onTick(self, tick)
        self.bg.updateTick(tick)

    # ----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        TargetPosTemplate.onBar(self, bar)
        self.bg.updateBar(bar)

    # ----------------------------------------------------------------------
    def onMyBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        # 保存K线数据
        am = self.am
        am.updateBar(bar)

        if not am.inited:
            return
        long_avg = np.sum(am.close[-self.m1:-1]) / self.m1
        high_price = am.high[-100:-1]
        low_price_for_atr = am.low[-100:-1]
        close_price = am.close[-100:-1]
        close_price_for_atr = close_price
        myatr = talib.ATR(high_price,
                          low_price_for_atr,
                          close_price_for_atr,
                          timeperiod=14)[-1]
        buyprice = long_avg + 2.5 * myatr
        sellprice = long_avg - 2.5 * myatr
        #做多
        if am.close[-1] > buyprice:
            self.setTargetPos(self.fixedSize)
        #做空
        if am.close[-1] < sellprice:
            self.setTargetPos(-self.fixedSize)
        #平仓
        if self.pos > 0 and am.close[-1] < long_avg:
            self.setTargetPos(0)
        if self.pos < 0 and am.close[-1] > long_avg:
            self.setTargetPos(0)

        # 同步数据到数据库
        self.saveSyncData()
        # 发出状态更新事件
        self.putEvent()

    # ----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    # ----------------------------------------------------------------------
    def onTrade(self, trade):
        # if self.pos != 0:
        #     # 多头开仓成交后,撤消空头委托
        #     if self.pos > 0:
        #         for shortOrderID in self.shortOrderIDList:
        #             self.cancelOrder(shortOrderID)
        #     # 反之同样
        #     elif self.pos < 0:
        #         for buyOrderID in self.buyOrderIDList:
        #             self.cancelOrder(buyOrderID)
        #
        #     # 移除委托号
        #     for orderID in (self.buyOrderIDList + self.shortOrderIDList):
        #         if orderID in self.orderList:
        #             self.orderList.remove(orderID)

        # 发出状态更新事件
        self.putEvent()

    # ----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 24
0
class BollingerBotStrategy01(CtaTemplate):
    """基于布林通道的交易策略"""
    className = 'BollingerBotStrategy01'
    author = 'Y.Raul'

    # 策略参数
    bollWindow = 28  # 通道窗口数
    entryDevUp = 4  # 开仓偏差
    entryDevDown = 3.2
    # exitDev = 1.2           # 平仓偏差
    # trailingPrcnt = 0.4
    # 移动止损百分比
    maWindow = 10  # 过滤用均线窗口
    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 策略变量
    bollMid = 0  # 布林带中轨
    bollStd = 0  # 布林带宽度
    entryUp = 0  # 开仓上轨
    # exitUp = 0                          # 平仓上轨
    entryDown = 0  #开仓下轨
    # exitDown = 0                        #平仓下轨

    dispacedLen = 0  #均线平移长度
    maFilter = 0  # 均线过滤
    maFilter1 = 0  # 上一期均线

    # 分级出场设置
    trailingStart1 = 20
    trailingStart2 = 30
    exitOnTrailingStop1 = 5  # Trailing Stop 距离
    exitOnTrailingStop2 = 10  # Trailing Stop 距离
    exitOnLossStop = 20  # Loss Stop 距离

    # 价格相关变量
    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点
    avgEntryPrice = 0
    minDiff = 1
    trailingExit = 0  #
    stopExit = 0  # 空头止损
    # longEntry = 0  # 多头开仓
    # shortEntry = 0

    # 信号相关变量
    buySig = False
    shortSig = False
    sellSig = False
    coverSig = False
    # entrusted = False #是否已有委托

    orderList = []  # 保存委托代码的列表

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'bollWindow', 'entryDevUp',
        'entryDevDown', 'trailingStart1', 'trailingStart2',
        'exitOnTrailingStop1', 'exitOnTrailingStop2', 'maWindow', 'initDays',
        'fixedSize'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'buySig', 'shortSig', 'sellSig',
        'coverSig', 'entryUp', 'entryDown', 'trailingExit', 'stopExit',
        'intraTradeHigh', 'intraTradeLow', 'avgEntryPrice'
    ]

    # 同步列表
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(BollingerBotStrategy01, self).__init__(ctaEngine, setting)

        self.bm = BarGenerator(self.onBar, 5, self.onFiveBar)
        self.am = ArrayManager(30)
        self.orderList = []
        self.entryPriceList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog('%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog('%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog('%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bm.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        # 观察周期1 Min,根据信号进行交易
        # 回测数据传送的bar.datetime,为bar的开始时间
        self.bm.updateBar(bar)
        # if not self.trading:
        #     return

        self.date = bar.date
        self.time = bar.time
        # 检查交易信号
        if self.buySig:
            res = self.buy(bar.close, self.fixedSize, True)
            self.orderList.extend([x.split('.')[1] for x in res])
            # self.orderList.extend(res.split('.')[1])

            # self.entryPriceList.append(self.longEntry)
            # self.avgEntryPrice = sum(self.entryPriceList) / len(self.entryPriceList)
            # self.LossStopPrice = round(self.avgEntryPrice * (100.0 + self.exitOnLossStop) / 100)

            # self.intraTradeHigh = max(bar.high, self.avgEntryPrice)
            # self.intraTradeLow = min(bar.low, self.avgEntryPrice)
            # log = "-----" * 10 + "\n@onBar\n" + \
            #       "bar.datetime: {0}; pos: {1} \n".format(bar.datetime, self.pos) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig) + \
            #       "sellSig: {0}; coverSig: {1}\n".format(self.sellSig, self.coverSig) + \
            #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #       "intraTradeLow: {0}\n".format(self.intraTradeLow)
            # self.writeCtaLog(log)
            # 记录log
            # log = "\n Trading: {0}\n".format(self.trading) + \
            #       "{0} Buy : longEntry: {1};\n".format(bar.datetime, bar.close) + \
            #       " entryUp:{0}; maFilter:{1}; maFilter1:{2}; \n".format(self.entryUp, self.maFilter, self.maFilter1)
            # self.writeCtaLog(log)
            self.buySig = False
            self.saveSyncData()
            # return

        if self.shortSig:
            self.res = self.short(bar.close, self.fixedSize, True)
            self.orderList.extend([x.split('.')[1] for x in self.res])
            # self.orderList.extend(res.split('.')[1])

            # self.LossStopPrice = round(self.shortEntry * (100.0 + self.exitOnLossStop) / 100)
            # self.entryPriceList.append(self.shortEntry)
            # self.avgEntryPrice = sum(self.entryPriceList) / len(self.entryPriceList)
            # self.LossStopPrice = round(self.avgEntryPrice * (100.0 + self.exitOnLossStop) / 100)
            #
            # self.intraTradeHigh = max(bar.high, self.avgEntryPrice)
            # self.intraTradeLow = min(bar.low, self.avgEntryPrice)
            # log = "-----" * 10 + "\n@onBar\n" + \
            #       "bar.datetime: {0}; pos: {1} \n".format(bar.datetime, self.pos) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig) + \
            #       "sellSig: {0}; coverSig: {1}\n".format(self.sellSig, self.coverSig) + \
            #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #       "intraTradeLow: {0}\n".format(self.intraTradeLow)
            # self.writeCtaLog(log)
            # # 记录log
            # log = "\n Trading: {0}\n".format(self.trading) + \
            #       "{0} Short : shortEntry: {1};\n".format(bar.datetime, bar.close) + \
            #       " entryDown:{0}; maFilter:{1}; maFilter1:{2}; \n".format(self.entryDown, self.maFilter, self.maFilter1)
            # self.writeCtaLog(log)

            self.shortSig = False
            self.saveSyncData()
            # return

        if self.sellSig:
            if bar.close > self.stopExit:
                price = self.trailingExit
            else:
                price = bar.close
            res = self.sell(price, abs(self.pos), True)
            # self.orderList.extend(res)
            # log = "-----" * 10 + "\n@onBar\n" + \
            #       "bar.datetime: {0}; pos: {1} \n".format(bar.datetime, self.pos) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig) + \
            #       "sellSig: {0}; coverSig: {1}\n".format(self.sellSig, self.coverSig) + \
            #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #       "intraTradeLow: {0}\n".format(self.intraTradeLow)
            # self.writeCtaLog(log)
            # # 记录log
            # log = "\n Trading: {0}\n".format(self.trading) + \
            #       "{0} Sell : {1};\n".format(bar.datetime, bar.close) + \
            #       " price:{0}; stopExit: {1}\n".format(price,self.stopExit)
            # self.writeCtaLog(log)

            # self.entryPriceList = []
            # self.avgEntryPrice = 0
            # self.stopExit = 0
            self.sellSig = False
            self.saveSyncData()
            # return

        if self.coverSig:
            if bar.close < self.stopExit:
                price = self.trailingExit
            else:
                price = bar.close
            res = self.cover(price, abs(self.pos), True)
            # self.orderList.extend(res)
            # log = "-----" * 10 + "\n@onBar\n" + \
            #       "bar.datetime: {0}; pos: {1} \n".format(bar.datetime, self.pos) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig) + \
            #       "sellSig: {0}; coverSig: {1}\n".format(self.sellSig, self.coverSig) + \
            #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #       "intraTradeLow: {0}\n".format(self.intraTradeLow)
            # self.writeCtaLog(log)
            # # 记录log
            # log = "\n Trading: {0}\n".format(self.trading) + \
            #       "{0} Cover : {1};\n".format(bar.datetime, bar.close) + \
            #       " price:{0}; stopExit: {1}\n".format(price,self.stopExit)
            # self.writeCtaLog(log)

            # self.entryPriceList = []
            # self.avgEntryPrice = 0
            # self.stopExit = 0
            self.coverSig = False
            self.saveSyncData()
            # return

        self.putEvent()

    #----------------------------------------------------------------------
    def onFiveBar(self, bar):
        """收到5分钟K线"""
        # 策略周期5Min,生成交易信号
        # 保存K线数据
        self.am.updateBar(bar)

        if not self.am.inited:
            return

        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        self.cancelAll()

        # 计算指标数值
        self.bollMid = self.am.sma(self.bollWindow,
                                   True)[-1 * (self.dispacedLen + 1)]
        self.bollStd = self.am.std(self.bollWindow)
        self.entryUp = round(self.bollMid + self.bollStd * self.entryDevUp)
        self.entryDown = round(self.bollMid - self.bollStd * self.entryDevDown)
        maArray = self.am.sma(self.maWindow, True)
        self.maFilter = round(maArray[-1])
        self.maFilter1 = round(maArray[-2])

        # 判断是否要进行交易
        # 当前无仓位
        if self.pos == 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = bar.low
            self.entryPriceList = []
            self.orderList = []
            self.avgEntryPrice = 0

            if bar.close > self.maFilter and self.maFilter > self.maFilter1:
                # 均线多头过滤
                if bar.close >= self.entryUp:
                    # 上轨突破
                    self.buySig = True

            if bar.close < self.maFilter and self.maFilter < self.maFilter1:
                # 均线空头过滤
                if bar.close <= self.entryDown:
                    # 下轨突破
                    self.shortSig = True

            # log = "-----" * 10 + "\n@onFiveBar\n" + \
            #       "bar.datetime: {0}; pos: {1} ; close: {2}\n".format(bar.datetime, self.pos,bar.close) + \
            #       "buySig: {0}; shortSig: {1}\n".format(self.buySig, self.shortSig) + \
            #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
            #       "intraTradeLow: {0}\n".format(self.intraTradeLow)
            # self.writeCtaLog(log)

        # 当前有仓位
        else:
            self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
            self.intraTradeLow = min(self.intraTradeLow, bar.low)

            if self.pos > 0:
                # self.stopExit = self.avgEntryPrice - self.exitOnLossStop * self.minDiff #固定止损价位

                if self.intraTradeHigh >= self.avgEntryPrice + self.trailingStart2 * self.minDiff:
                    # 二级止赢判断 盈利80跳
                    if (bar.close <= self.intraTradeHigh -
                            self.exitOnTrailingStop2 * self.minDiff):
                        # 回撤20跳
                        self.trailingExit = self.intraTradeHigh - self.exitOnTrailingStop2 * self.minDiff
                        self.sellSig = True
                        # if bar.close < self.longExit:
                        #     self.longExit = bar.close
                        # 记录log
                        # log = "\n{0} Sell(Trailing Stop2)\n".format(bar.datetime) + \
                        #     'bar.close: {0}; bar.low: {1}; longExit: {2}'.format(bar.close,bar.low, self.longExit)+ \
                        #     'intraTradeHigh: {0}; avgEntryPrice: {1}; bar.open: {2}'.format(self.intraTradeHigh,self.avgEntryPrice, bar.open)
                        # self.writeCtaLog(log)

                elif self.intraTradeHigh >= self.avgEntryPrice + self.trailingStart1 * self.minDiff:
                    # 一级止赢判断,盈利50跳
                    if (bar.close <= self.intraTradeHigh -
                            self.exitOnTrailingStop1 * self.minDiff):
                        # 回撤20跳
                        self.trailingExit = self.intraTradeHigh - self.exitOnTrailingStop1 * self.minDiff
                        self.sellSig = True
                        # if bar.close < self.longExit:
                        #     self.longExit = bar.close
                        # 记录log
                        # log = "\n{0} Sell(Trailing Stop1)\n".format(bar.datetime) + \
                        #       'bar.close: {0}; bar.low: {1}; longExit: {2}'.format(bar.close, bar.low,
                        #                                                            self.longExit)+ \
                        #       'intraTradeHigh: {0}; avgEntryPrice: {1}; bar.open: {2}'.format(self.intraTradeHigh,self.avgEntryPrice, bar.open)
                        # self.writeCtaLog(log)
                elif self.stopExit != 0:
                    if (bar.close <= self.stopExit):
                        # 固定止损,回撤20跳
                        self.sellSig = True
                # log = "-----" * 10 + "\n@onFiveBar\n" + \
                #       "bar.datetime: {0}; pos: {1} ; close:{2}\n".format(bar.datetime, self.pos, bar.close) + \
                #       "sellSig: {0}; coverSig: {1}\n".format(self.sellSig, self.coverSig) + \
                #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
                #       "intraTradeLow: {0}\n".format(self.intraTradeLow) + \
                #       "trailingStart1: {0}\n".format(self.avgEntryPrice + self.trailingStart1 * self.minDiff) + \
                #       "trailingStart2: {0}\n".format(self.avgEntryPrice + self.trailingStart2 * self.minDiff) + \
                #       "avgEntryPrice: {0}\n".format(self.avgEntryPrice) + \
                #       "trailingStop: {0}\n".format(self.trailingExit) + \
                #       "stopExit: {0}\n".format(self.stopExit)
                #
                # self.writeCtaLog(log)
                # if bar.close < self.longExit:
                #     self.longExit = bar.close
                # 记录log
                # log = "\n{0} Sell(Loss Stop)\n".format(bar.datetime) + \
                #       'bar.close: {0}; bar.low: {1}; longExit: {2}'.format(bar.close, bar.low,
                #                                                            self.longExit)+ \
                #       'intraTradeHigh: {0}; avgEntryPrice: {1}; bar.open: {2}'.format(self.intraTradeHigh,
                #                                                                       self.avgEntryPrice,
                #                                                                       bar.open)
                # self.writeCtaLog(log)

            elif self.pos < 0:
                # self.stopExit = self.avgEntryPrice + self.exitOnLossStop * self.minDiff #固定止损价
                if self.intraTradeLow <= self.avgEntryPrice - self.trailingStart2 * self.minDiff:
                    # 二级止赢判断 盈利80跳
                    if (bar.close >= self.intraTradeLow +
                            self.exitOnTrailingStop2 * self.minDiff):
                        # 回撤20跳
                        self.trailingExit = self.intraTradeLow + self.exitOnTrailingStop2 * self.minDiff
                        self.coverSig = True
                        # if bar.close > self.shortExit:
                        #     self.shortExit = bar.close
                        # 记录log
                        # log = "\n{0} Cover(Trailing Stop1)\n".format(bar.datetime) + \
                        #       'bar.close: {0}; bar.low: {1}; shortExit: {2}'.format(bar.close, bar.low,
                        #                                                            self.shortExit)+ \
                        #       'intraTradeLow: {0}; avgEntryPrice: {1}; bar.open: {2}'.format(self.intraTradeLow,
                        #                                                                       self.avgEntryPrice,
                        #                                                                       bar.open)
                        # self.writeCtaLog(log)

                elif self.intraTradeLow <= self.avgEntryPrice - self.trailingStart1 * self.minDiff:
                    # 一级止赢判断,盈利50跳
                    if (bar.close >= self.intraTradeLow +
                            self.exitOnTrailingStop1 * self.minDiff):
                        # 回撤20跳
                        self.trailingExit = self.intraTradeLow + self.exitOnTrailingStop1 * self.minDiff
                        self.coverSig = True
                        # if bar.close > self.shortExit:
                        #     self.shortExit = bar.close
                        # 记录log
                        # log = "\n{0} Cover(Trailing Stop2)\n".format(bar.datetime) + \
                        #       'bar.close: {0}; bar.low: {1}; shortExit: {2}'.format(bar.close, bar.low,
                        #                                                            self.shortExit)+ \
                        #       'intraTradeLow: {0}; avgEntryPrice: {1}; bar.open: {2}'.format(self.intraTradeLow,
                        #                                                                      self.avgEntryPrice,
                        #                                                                      bar.open)
                        # self.writeCtaLog(log)
                elif self.stopExit != 0:
                    if (bar.close >= self.stopExit):
                        # 固定止损,回撤20跳
                        # self.shortExit = self.avgEntryPrice + self.exitOnLossStop * self.minDiff
                        self.coverSig = True
                # if bar.close > self.shortExit:
                #     self.shortExit = bar.close
                # 记录log
                # log = "\n{0} Cover(Loss Stop)\n".format(bar.datetime) + \
                #       'bar.close: {0}; bar.low: {1}; shortExit: {2}'.format(bar.close, bar.low,
                #                                                             self.shortExit)+ \
                #       'intraTradeLow: {0}; avgEntryPrice: {1}; bar.open: {2}'.format(self.intraTradeLow,
                #                                                                      self.avgEntryPrice,
                #                                                                      bar.open)
                # self.writeCtaLog(log)

                # log = "-----" * 10 + "\n@onFiveBar\n" + \
                #       "bar.datetime: {0}; pos: {1} ; close:{2}\n".format(bar.datetime, self.pos, bar.close) + \
                #       "sellSig: {0}; coverSig: {1}\n".format(self.sellSig, self.coverSig) + \
                #       "intraTradeHigh: {0}\n".format(self.intraTradeHigh) + \
                #       "intraTradeLow: {0}\n".format(self.intraTradeLow) + \
                #       "trailingStart1: {0}\n".format(self.avgEntryPrice - self.trailingStart1 * self.minDiff)+\
                #       "trailingStart2: {0}\n".format(self.avgEntryPrice - self.trailingStart2 * self.minDiff)+\
                #       "avgEntryPrice: {0}\n".format(self.avgEntryPrice)+\
                #       "trailingStop: {0}\n".format(self.trailingExit)+\
                #       "stopExit: {0}\n".format(self.stopExit)
                #
                # self.writeCtaLog(log)

        # 发出状态更新事件
        self.saveSyncData()
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        # CTA引擎中涉及到的交易方向类型
        # CTAORDER_BUY = u'买开'
        # CTAORDER_SELL = u'卖平'
        # CTAORDER_SHORT = u'卖开'
        # CTAORDER_COVER = u'买平'
        # log = "-----" * 10 + "\n@onOrder\n" + \
        #       "orderTime: {0}; pos: {1} \n".format(order.orderTime, order.totalVolume) + \
        #       "status {0}; vtOrderID: {1}\n".format(order.status, order.vtOrderID)
        # self.writeCtaLog(log)

        # 对于开仓,记录相关价格
        # if order.vtOrderID in self.orderList:
        if order.direction == DIRECTION_LONG and order.offset == OFFSET_OPEN:
            if order.totalVolume == order.tradedVolume:
                # 更新入场价列表,更新平均入场价
                self.entryPriceList.append(order.price)
                self.avgEntryPrice = sum(self.entryPriceList) / len(
                    self.entryPriceList)
                self.stopExit = self.avgEntryPrice - self.exitOnLossStop * self.minDiff  # 固定止损价
                # self.orderList.remove(order.vtOrderID)

        elif order.direction == DIRECTION_SHORT and order.offset == OFFSET_OPEN:
            # 更新入场价列表,更新平均入场价
            if order.totalVolume == order.tradedVolume:
                # 更新入场价列表,更新平均入场价
                self.entryPriceList.append(order.price)
                self.avgEntryPrice = sum(self.entryPriceList) / len(
                    self.entryPriceList)
                self.stopExit = self.avgEntryPrice + self.exitOnLossStop * self.minDiff  # 固定止损价
                # self.orderList.remove(order.vtOrderID)

        self.putEvent()

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # 发出状态更新事件
        data = trade.__dict__

        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        data = so.__dict__
        self.putEvent()
Ejemplo n.º 25
0
class MultiTimeframeStrategy(CtaTemplate):
    """跨时间周期交易策略"""
    className = 'MultiTimeframeStrategy'
    author = u'用Python的交易员'

    # 策略参数
    rsiSignal = 20  # RSI信号阈值
    rsiWindow = 14  # RSI窗口
    fastWindow = 5  # 快速均线窗口
    slowWindow = 20  # 慢速均线窗口

    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 策略变量
    rsiValue = 0  # RSI指标的数值
    rsiLong = 0  # RSI买开阈值
    rsiShort = 0  # RSI卖开阈值
    fastMa = 0  # 5分钟快速均线
    slowMa = 0  # 5分钟慢速均线
    maTrend = 0  # 均线趋势,多头1,空头-1

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'rsiSignal', 'rsiWindow',
        'fastWindow', 'slowWindow'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'rsiValue', 'rsiLong', 'rsiShort',
        'fastMa', 'slowMa', 'maTrend'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(MultiTimeframeStrategy, self).__init__(ctaEngine, setting)

        self.rsiLong = 50 + self.rsiSignal
        self.rsiShort = 50 - self.rsiSignal

        # 创建K线合成器对象
        self.bg5 = BarGenerator(self.onBar, 5, self.on5MinBar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar)
        self.am15 = ArrayManager()

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        # 只需要要在一个BarGenerator中合成1分钟K线
        self.bg5.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        # 基于15分钟判断趋势过滤,因此先更新
        self.bg15.updateBar(bar)

        # 基于5分钟判断
        self.bg5.updateBar(bar)

    #----------------------------------------------------------------------
    def on5MinBar(self, bar):
        """5分钟K线"""
        self.cancelAll()

        # 保存K线数据
        self.am5.updateBar(bar)
        if not self.am5.inited:
            return

        # 如果15分钟数据尚未初始化完毕,则直接返回
        if not self.maTrend:
            return

        # 计算指标数值
        self.rsiValue = self.am5.rsi(self.rsiWindow)

        # 判断是否要进行交易

        # 当前无仓位
        if self.pos == 0:
            if self.maTrend > 0 and self.rsiValue >= self.rsiLong:
                self.buy(bar.close + 5, self.fixedSize)

            elif self.maTrend < 0 and self.rsiValue <= self.rsiShort:
                self.short(bar.close - 5, self.fixedSize)

        # 持有多头仓位
        elif self.pos > 0:
            if self.maTrend < 0 or self.rsiValue < 50:
                self.sell(bar.close - 5, abs(self.pos))

        # 持有空头仓位
        elif self.pos < 0:
            if self.maTrend > 0 or self.rsiValue > 50:
                self.cover(bar.close + 5, abs(self.pos))

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def on15MinBar(self, bar):
        """15分钟K线推送"""
        self.am15.updateBar(bar)

        if not self.am15.inited:
            return

        # 计算均线并判断趋势
        self.fastMa = self.am15.sma(self.fastWindow)
        self.slowMa = self.am15.sma(self.slowWindow)

        if self.fastMa > self.slowMa:
            self.maTrend = 1
        else:
            self.maTrend = -1

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 26
0
class MacdMaStrategy(CtaTemplate):
    """基于MacdMa的交易策略"""
    className = 'MacdMaStrategy'
    author = u'用Python的交易员'

    # 策略参数
    initDays = 20  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量
    trailingPercent = 0.8  # 百分比移动止损
    openBuy = True  # 开多仓
    openShort = False  # 开空仓
    stoploss = 20  # 固定止损
    stopfit = 60  # 固定止盈
    trailingloss = 30  # 移动止损
    # 策略变量

    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点
    lastPrice = 0  # 持仓价
    maBuy = False  # MA买入
    maShort = False  # MA卖出
    macdBuy = False  # MACD买入
    macdShort = False  # MACD卖出
    macdOpen = False
    count = 0  # 持仓周期

    fastMa = 0
    slowMa = 0
    dif = 0
    dea = 0

    buyOrderIDList = []  # OCO委托买入开仓的委托号
    shortOrderIDList = []  # OCO委托卖出开仓的委托号
    orderList = []  # 保存委托代码的列表

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'openBuy', 'openShort'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'fastMa', 'slowMa', 'dif', 'dea', 'maBuy',
        'maShort', 'macdBuy', 'macdShort', 'macdOpen', 'lastPrice', 'count'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow', 'lastPrice', 'count']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(MacdMaStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 5, self.onFiveBar)  # 创建K线合成器对象
        self.am = ArrayManager()

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bg.updateBar(bar)
        self.putEvent()

    #----------------------------------------------------------------------
    def onFiveBar(self, bar):
        """收到15分钟K线"""
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        for orderID in self.orderList:
            self.cancelOrder(orderID)
        self.orderList = []

        # 保存K线数据
        am = self.am
        am.updateBar(bar)

        # if not am.inited:
        #     return

        # 计算指标数值

        dif = talib.EMA(am.close, 12) - talib.EMA(am.close, 26)
        dea = talib.EMA(dif, 9)
        fast_ma = talib.MA(am.close, 5)
        slow_ma = talib.MA(am.close, 13)
        self.fastMa = fast_ma[-1]
        self.slowMa = slow_ma[-1]
        self.dif = dif[-1]
        self.dea = dea[-1]
        #self.macdbar = macdbar[-1]

        if self.pos == 0:
            self.intraTradeHigh = bar.high
            self.intraTradeLow = bar.low
            self.lastPrice = bar.close
            self.count = 0

        elif self.pos > 0:
            self.count += 1
            # # 计算多头持有期内的最高价,以及重置最低价
            # self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
            # self.intraTradeLow = bar.low
            #
            # # 计算多头移动止损
            # longStop = self.intraTradeHigh * (1 - self.trailingPercent / 100)
            #
            # # 发出本地止损委托
            # self.sell(longStop, abs(self.pos), stop=True)
            # 固定止损
            self.sell(self.lastPrice - self.stoploss,
                      self.fixedSize,
                      stop=True)
            # 固定止盈
            self.sell(self.lastPrice + self.stopfit, self.fixedSize, stop=True)

            if self.count >= 36:
                self.sell(bar.close - 5, abs(self.pos))

        # 持有空头仓位
        elif self.pos < 0:
            self.count += 1
            # # 计算空头持有期内的最高价,以及重置最低价
            # self.intraTradeLow = min(self.intraTradeLow, bar.low)
            # self.intraTradeHigh = bar.high
            # # 计算空头移动止损
            # shortStop = self.intraTradeLow * (1 + self.trailingPercent / 100)
            # # 发出本地止损委托
            # self.cover(shortStop, abs(self.pos), stop=True)
            # 固定止损
            self.cover(self.lastPrice + self.stoploss,
                       self.fixedSize,
                       stop=True)
            # 固定止盈
            self.cover(self.lastPrice - self.stopfit,
                       self.fixedSize,
                       stop=True)

            if self.count >= 36:
                self.cover(bar.close + 5, abs(self.pos))

        # 判断是否要进行交易

        # 多头
        if fast_ma[-1] > slow_ma[-1] and fast_ma[-2] < slow_ma[-2]:
            self.writeCtaLog(u'%s策略均线金叉' % self.name)
            self.maBuy = True
            self.maShort = False

        # 空头

        if fast_ma[-1] < slow_ma[-1] and fast_ma[-2] > slow_ma[-2]:
            self.writeCtaLog(u'%s策略均线死叉' % self.name)
            self.maShort = True
            self.maBuy = False

        if abs(dif[-1]) < 3 or abs(dea[-1] < 3):
            self.writeCtaLog(u'%s策略MACD进入可交易区间' % self.name)
            self.macdOpen = True
        else:
            self.writeCtaLog(u'%s策略MACD离开可交易区间' % self.name)
            self.macdOpen = False

        if dif[-1] > dea[-1] and dif[-2] < dea[-2] and self.macdOpen:
            self.writeCtaLog(u'%s策略MACD交易区域内金叉' % self.name)
            self.macdBuy = True
            self.macdShort = False

        if dif[-1] < dea[-1] and dif[-2] > dea[-2] and self.macdOpen:
            self.writeCtaLog(u'%s策略MACD交易区域内死叉' % self.name)
            self.macdShort = True
            self.macdBuy = False

        if self.pos == 0:
            # 买入
            if self.openBuy and self.maBuy and self.macdBuy:
                orderID = self.buy(bar.close + 5, self.fixedSize)
                self.orderList.extend(orderID)

            # 卖出
            if self.openShort and self.maShort and self.macdShort:
                orderID = self.short(bar.close - 5, self.fixedSize)
                self.orderList.extend(orderID)

        # 同步数据到数据库
        self.saveSyncData()

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 27
0
class DualThrustStrategy(CtaTemplate):
    """DualThrust交易策略"""
    className = 'DualThrustStrategy'
    author = u'用Python的交易员'

    # 策略参数
    fixedSize = 100
    k1 = 0.4
    k2 = 0.6

    initDays = 10

    # 策略变量
    barList = []  # K线对象的列表

    dayOpen = 0
    dayHigh = 0
    dayLow = 0

    range = 0
    longEntry = 0
    shortEntry = 0
    exitTime = time(hour=14, minute=55)

    longEntered = False
    shortEntered = False

    # 参数列表,保存了参数的名称
    paramList = ['name', 'className', 'author', 'vtSymbol', 'k1', 'k2']

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'range', 'longEntry', 'shortEntry',
        'exitTime'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(DualThrustStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar)
        self.barList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        self.cancelAll()

        # 计算指标数值
        self.barList.append(bar)

        if len(self.barList) <= 2:
            return
        else:
            self.barList.pop(0)
        lastBar = self.barList[-2]

        # 新的一天
        if lastBar.datetime.date() != bar.datetime.date():
            # 如果已经初始化
            if self.dayHigh:
                self.range = self.dayHigh - self.dayLow
                self.longEntry = bar.open + self.k1 * self.range
                self.shortEntry = bar.open - self.k2 * self.range

            self.dayOpen = bar.open
            self.dayHigh = bar.high
            self.dayLow = bar.low

            self.longEntered = False
            self.shortEntered = False
        else:
            self.dayHigh = max(self.dayHigh, bar.high)
            self.dayLow = min(self.dayLow, bar.low)

        # 尚未到收盘
        if not self.range:
            return

        if bar.datetime.time() < self.exitTime:
            if self.pos == 0:
                if bar.close > self.dayOpen:
                    if not self.longEntered:
                        self.buy(self.longEntry, self.fixedSize, stop=True)
                else:
                    if not self.shortEntered:
                        self.short(self.shortEntry, self.fixedSize, stop=True)

            # 持有多头仓位
            elif self.pos > 0:
                self.longEntered = True

                # 多头止损单
                self.sell(self.shortEntry, self.fixedSize, stop=True)

                # 空头开仓单
                if not self.shortEntered:
                    self.short(self.shortEntry, self.fixedSize, stop=True)

            # 持有空头仓位
            elif self.pos < 0:
                self.shortEntered = True

                # 空头止损单
                self.cover(self.longEntry, self.fixedSize, stop=True)

                # 多头开仓单
                if not self.longEntered:
                    self.buy(self.longEntry, self.fixedSize, stop=True)

        # 收盘平仓
        else:
            if self.pos > 0:
                self.sell(bar.close * 0.99, abs(self.pos))
            elif self.pos < 0:
                self.cover(bar.close * 1.01, abs(self.pos))

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 28
0
class TurtleTradingStrategy(CtaTemplate):
    """海龟交易策略"""
    className = 'TurtleTradingStrategy'
    author = u'用Python的交易员'

    # 策略参数
    entryWindow = 55  # 入场通道窗口
    exitWindow = 20  # 出场通道窗口
    atrWindow = 20  # 计算ATR波动率的窗口
    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 策略变量
    entryUp = 0  # 入场通道上轨
    entryDown = 0  # 入场通道下轨
    exitUp = 0  # 出场通道上轨
    exitDown = 0  # 出场通道下轨
    atrVolatility = 0  # ATR波动率

    longEntry = 0  # 多头入场价格
    shortEntry = 0  # 空头入场价格
    longStop = 0  # 多头止损价格
    shortStop = 0  # 空头止损价格

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'entryWindow', 'exitWindow',
        'atrWindow', 'initDays', 'fixedSize'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'entryUp', 'entryDown', 'exitUp',
        'exitDown', 'longEntry', 'shortEntry', 'longStop', 'shortStop'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(TurtleTradingStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.cancelAll()

        # 保存K线数据
        self.am.updateBar(bar)
        if not self.am.inited:
            return

        # 计算指标数值
        self.entryUp, self.entryDown = self.am.donchian(self.entryWindow)
        self.exitUp, self.exitDown = self.am.donchian(self.exitWindow)

        if not self.pos:
            self.atrVolatility = self.am.atr(self.atrWindow)

        # 判断是否要进行交易
        if self.pos == 0:
            self.longEntry = 0
            self.shortEntry = 0
            self.longStop = 0
            self.shortStop = 0

            self.sendBuyOrders(self.entryUp)
            self.sendShortOrders(self.entryDown)

        elif self.pos > 0:
            # 加仓逻辑
            self.sendBuyOrders(self.longEntry)

            # 止损逻辑
            sellPrice = max(self.longStop, self.exitDown)
            self.sell(sellPrice, abs(self.pos), True)

        elif self.pos < 0:
            # 加仓逻辑
            self.sendShortOrders(self.shortEntry)

            # 止损逻辑
            coverPrice = min(self.shortStop, self.exitUp)
            self.cover(coverPrice, abs(self.pos), True)

        # 同步数据到数据库
        self.saveSyncData()

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        """成交推送"""
        if trade.direction == DIRECTION_LONG:
            self.longEntry = trade.price
            self.longStop = self.longEntry - self.atrVolatility * 2
        else:
            self.shortEntry = trade.price
            self.shortStop = self.shortEntry + self.atrVolatility * 2

        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass

    #----------------------------------------------------------------------
    def sendBuyOrders(self, price):
        """发出一系列的买入停止单"""
        t = self.pos / self.fixedSize

        if t < 1:
            self.buy(price, self.fixedSize, True)

        if t < 2:
            self.buy(price + self.atrVolatility * 0.5, self.fixedSize, True)

        if t < 3:
            self.buy(price + self.atrVolatility, self.fixedSize, True)

        if t < 4:
            self.buy(price + self.atrVolatility * 1.5, self.fixedSize, True)

    #----------------------------------------------------------------------
    def sendShortOrders(self, price):
        """"""
        t = self.pos / self.fixedSize

        if t > -1:
            self.short(price, self.fixedSize, True)

        if t > -2:
            self.short(price - self.atrVolatility * 0.5, self.fixedSize, True)

        if t > -3:
            self.short(price - self.atrVolatility, self.fixedSize, True)

        if t > -4:
            self.short(price - self.atrVolatility * 1.5, self.fixedSize, True)
Ejemplo n.º 29
0
class HorizBreakoutStrategy(CtaTemplate):
    """基于Adxr的交易策略"""
    className = 'AdxrStrategy'
    author = u'用Python的交易员'

    # 策略参数
    trailingPrcnt = 0.8  # 移动止损
    initDays = 30  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量
    aPeriod = 11  # 窗口数

    # 策略变量

    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点

    buy_high = 0
    sell_low = 0
    buy_price = 0
    sell_price = 0
    targetPos = 0

    buyOrderIDList = []  # OCO委托买入开仓的委托号
    shortOrderIDList = []  # OCO委托卖出开仓的委托号
    orderList = []  # 保存委托代码的列表

    # 参数列表,保存了参数的名称
    paramList = ['name', 'className', 'author', 'vtSymbol', 'aPeriod']

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'targetPos', 'buy_high', 'sell_low',
        'buy_price', 'sell_price'
    ]

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos', 'intraTradeHigh', 'intraTradeLow']

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(HorizBreakoutStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 30, self.onMyBar)  # 创建K线合成器对象
        self.am = ArrayManager(size=50)

        self.buyOrderIDList = []
        self.shortOrderIDList = []
        self.orderList = []

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

        self.putEvent()

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bg.updateBar(bar)
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        for orderID in self.orderList:
            self.cancelOrder(orderID)
            self.orderList = []

        if self.targetPos > 0:
            if self.pos == 0:
                orderID = self.buy(bar.close + 5, self.fixedSize)
                self.orderList.extend(orderID)
            if self.pos < 0:
                orderID = self.cover(bar.close + 5, abs(self.pos))
                self.orderList.extend(orderID)
                time.sleep(3)
                orderID = self.buy(bar.close + 5, self.fixedSize)
                self.orderList.extend(orderID)

        if self.targetPos < 0:
            if self.pos == 0:
                orderID = self.short(bar.close - 5, self.fixedSize)
                self.orderList.extend(orderID)
            if self.pos > 0:
                orderID = self.sell(bar.close - 5, abs(self.pos))
                self.orderList.extend(orderID)
                time.sleep(3)
                orderID = self.short(bar.close - 5, self.fixedSize)
                self.orderList.extend(orderID)

        if self.targetPos == 0:
            if self.pos > 0:
                orderID = self.sell(bar.close - 5, abs(self.pos))
                self.orderList.extend(orderID)
            if self.pos < 0:
                orderID = self.cover(bar.close + 5, abs(self.pos))
                self.orderList.extend(orderID)

    #----------------------------------------------------------------------
    def onMyBar(self, bar):
        """收到30分钟K线"""

        # 保存K线数据
        am = self.am
        am.updateBar(bar)

        if not am.inited:
            return

        # 计算指标数值

        h_high = max(am.high[-self.aPeriod:-1])
        l_low = min(am.low[-self.aPeriod:-1])

        vibrate = h_high - l_low < 0.04 * l_low
        # 判断是否要进行交易
        # 多头
        if vibrate and am.openArray[-1] + am.highArray[-1] + am.lowArray[
                -1] + am.closeArray[-1] > 4 * h_high:
            self.buy_price = am.close[-1]
            self.buy_high = am.high[-1]
            self.targetPos = self.fixedSize

        # 空头
        if vibrate and am.openArray[-1] + am.highArray[-1] + am.lowArray[
                -1] + am.closeArray[-1] < 4 * l_low:
            self.sell_price = am.close[-1]
            self.sell_low = am.low[-1]
            self.targetPos = -self.fixedSize

        if self.pos > 0 and am.high[-1] > self.buy_high:
            self.buy_high = am.high[-1]
        if self.pos < 0 and am.low[-1] < self.sell_low:
            self.sell_low = am.low[-1]

        # 平多头
        if self.pos > 0 and ((2 * am.close[-1] < self.buy_price + self.buy_high
                              and self.buy_high > self.buy_price + 40)
                             or am.close[-1] < l_low):
            # orderID = self.sell(bar.close - 5, abs(self.pos))
            # self.orderList.extend(orderID)
            self.targetPos = 0
        #平空头
        if self.pos < 0 and (
            (2 * am.close[-1] > self.sell_price + self.sell_low and
             self.sell_low < self.sell_price - 40) or am.close[-1] > h_high):
            # orderID = self.cover(bar.close + 5, abs(self.pos))
            # self.orderList.extend(orderID)
            self.targetPos = 0

        # 同步数据到数据库
        self.saveSyncData()
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        # if self.pos != 0:
        #     # 多头开仓成交后,撤消空头委托
        #     if self.pos > 0:
        #         for shortOrderID in self.shortOrderIDList:
        #             self.cancelOrder(shortOrderID)
        #     # 反之同样
        #     elif self.pos < 0:
        #         for buyOrderID in self.buyOrderIDList:
        #             self.cancelOrder(buyOrderID)
        #
        #     # 移除委托号
        #     for orderID in (self.buyOrderIDList + self.shortOrderIDList):
        #         if orderID in self.orderList:
        #             self.orderList.remove(orderID)

        # 发出状态更新事件
        #self.putEvent()
        pass

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
Ejemplo n.º 30
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(DualThrustStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar)
        self.barList = []