Ejemplo n.º 1
0
    def _xform_data(self, df):
        columns = []
        tables_ = data.get_tables(self.hypers.arbitrage)
        percent = self.hypers.pct_change
        for table in tables_:
            name, cols, ohlcv = table['name'], table['cols'], table.get(
                'ohlcv', {})
            columns += [self._diff(df[f'{name}_{k}'], percent) for k in cols]

            # Add extra indicator columns
            if ohlcv and self.hypers.indicators:
                ind = pd.DataFrame()
                # TA-Lib requires specifically-named columns (OHLCV)
                for k, v in ohlcv.items():
                    ind[k] = df[f"{name}_{v}"]
                columns += [
                    ## Original indicators from some boilerplate repo I started with
                    self._diff(SMA(ind, timeperiod=15), percent),
                    self._diff(SMA(ind, timeperiod=60), percent),
                    self._diff(RSI(ind, timeperiod=14), percent),
                    self._diff(ATR(ind, timeperiod=14), percent),

                    ## Indicators from the book "How to Day Trade For a Living". Not sure which are more solid...
                    ## Price, Volume, 9-EMA, 20-EMA, 50-SMA, 200-SMA, VWAP, prior-day-close
                    # self._diff(EMA(ind, timeperiod=9)),
                    # self._diff(EMA(ind, timeperiod=20)),
                    # self._diff(SMA(ind, timeperiod=50)),
                    # self._diff(SMA(ind, timeperiod=200)),
                ]

        states = np.nan_to_num(np.column_stack(columns))
        prices = df[data.target].values
        # Note: don't scale/normalize here, since we'll normalize w/ self.price/step_acc.cash after each action
        return states, prices
Ejemplo n.º 2
0
def ChartKBar_MA(KBar,longPeriod=20,shortPeriod=5):
    # 計算移動平均線(長短線)
    KBar['MA_long']=SMA(KBar,timeperiod=longPeriod)
    KBar['MA_short']=SMA(KBar,timeperiod=shortPeriod)
    # 將K線轉為DataFrame
    Kbar_df=KbarToDf(KBar)
    # 將副圖繪製出來
    addp=[]
    addp.append(mpf.make_addplot(Kbar_df['MA_long'],color='red'))
    addp.append(mpf.make_addplot(Kbar_df['MA_short'],color='yellow'))
    # 開始繪圖
    ChartKBar(KBar,addp,True)
Ejemplo n.º 3
0
    def algo_action(self):
        #数据转换,方便调用ta-lib函数进行技术指标的计算,这里用SMA指标
        close = np.asarray(self.close_buffer)
        ma = SMA({'close':close}, timeperiod=self.timeperiod)
        delta = round(close[-1] - ma[-1],4)     # 最新数据点,bar的收盘价跟ma的差
        last_ma = round(ma[-1], 4)  #  均线ma的最新值
        momentum = round(self.last_price - last_ma,4)  # 当前最新价格跟ma之间的差,成交价相对ma偏离
        cross = (close[-1] - ma[-1]) * (close[-3] - ma[-3]) < 0  ## 判断有否交叉
        #print 'close: ', close
        print(('close ma delta: {0}, last_ma: {1}, momentum: {2}'.format(delta, last_ma, momentum)))

        b_p = self.get_position(self.exchange, self.sec_id, OrderSide_Bid)    #查询策略所持有的多仓
        # 打印持仓信息
        print(('pos long: {0} vwap: {1:.2f}'.format(b_p.volume if b_p else 0.0, b_p.vwap if b_p else 0.0)))
        if cross < 0 and delta > threshold and momentum >= significant_diff:        ## 收盘价上穿均线,且当前价格偏离满足门限过滤条件,多信号
            # 没有超出下单次数限制
            if self.trade_count < self.trade_limit:
                # 依次获取下单的交易量,下单量是配置的一个整数数列,用于仓位管理,可用配置文件中设置
                vol = self.trade_unit[self.trade_count]
                # 如果本次下单量大于0,  发出买入委托交易指令
                if vol > eps:
                    self.open_long(self.exchange, self.sec_id, self.last_price, vol)
                self.trade_count += 1    #增加计数
        elif cross < 0 and delta < -threshold and momentum <= - significant_diff:     ## bar 收盘价下穿ma均线,且偏离满足信号过滤条件
            # 超出下单次数限制
            if b_p and b_p.available_yesterday > eps:
                self.close_long(self.exchange, self.sec_id, self.last_price, b_p.available_yesterday)
                self.trade_count = 0
        else:       ##  其他情况,忽略不处理
            pass
Ejemplo n.º 4
0
    def sma(self, data, length, price_input='close'):
        sma_values = {'success': True, 'result': {'data': None, 'current': None}}#, 'state': None}}

        data_copy = data.copy()

        try:
            # uses open prices?
            results = SMA(data_copy, timeperiod=length, price='close')

            sma_values['result']['data'] = results

            sma_values['result']['current'] = results[-1]

            if self.serialize_numpy == True:
                sma_values['result']['data'] = sma_values['result']['data'].tolist()

        except Exception as e:
            logger.exception('Exception while calculating SMA.')
            logger.exception(e)

            sma_values['success'] = False

        finally:
            return sma_values
Ejemplo n.º 5
0
    def __init__(self, candles: dict, indicator_info: dict):
        self.candles = candles
        self.LENGTH = indicator_info[LENGTH]

        self.MA = SMA(candles, timeperiod=self.LENGTH)
Ejemplo n.º 6
0
    def algo_action(self):
        #数据转换,方便调用ta-lib函数进行技术指标的计算,这里用SMA指标
        close = np.asarray(self.close_buffer)
        ma = SMA({'close': close}, timeperiod=self.timeperiod)
        delta = round(close[-1] - ma[-1], 4)  # 最新数据点,bar的收盘价跟ma的差
        last_ma = round(ma[-1], 4)  #  均线ma的最新值
        momentum = round(self.last_price - last_ma,
                         4)  # 当前最新价格跟ma之间的差,成交价相对ma偏离
        #print 'close: ', close
        print('close ma delta: {0}, last_ma: {1}, momentum: {2}'.format(
            delta, last_ma, momentum))

        a_p = self.get_position(self.exchange, self.sec_id,
                                OrderSide_Ask)  #查询策略所持有的空仓
        b_p = self.get_position(self.exchange, self.sec_id,
                                OrderSide_Bid)  #查询策略所持有的多仓
        # 打印持仓信息
        print('pos long: {0} vwap: {1}, pos short: {2}, vwap: {3}'.format(
            b_p.volume if b_p else 0.0,
            round(b_p.vwap, 2) if b_p else 0.0, a_p.volume if a_p else 0.0,
            round(a_p.vwap, 2) if a_p else 0.0))
        if delta > threshold and momentum >= significant_diff:  ## 收盘价上穿均线,且当前价格偏离满足门限过滤条件,多信号
            # 没有空仓,且没有超出下单次数限制
            if (a_p is None or
                    a_p.volume < eps) and self.trade_count < self.trade_limit:
                # 依次获取下单的交易量,下单量是配置的一个整数数列,用于仓位管理,可用配置文件中设置
                vol = self.trade_unit[self.trade_count]
                # 如果本次下单量大于0,  发出买入委托交易指令
                if vol > eps:
                    self.open_long(self.exchange, self.sec_id, self.last_price,
                                   vol)
                self.trade_count += 1  #增加计数
            else:
                #  如果有空仓,且达到本次信号的交易次数上限
                if a_p and a_p.volume > eps and self.trade_count == self.trade_limit:
                    self.close_short(self.exchange, self.sec_id,
                                     self.last_price, a_p.volume)  # 平掉所有空仓
                    self.trade_count = 0
                else:
                    # 有空仓时,且上次交易信号后没达到交易次数限制,继续加空
                    vol = self.trade_unit[
                        self.
                        trade_count] if self.trade_count < self.trade_limit else 0.0
                    self.trade_count += 1
                    if vol > eps:
                        self.open_short(self.exchange, self.sec_id,
                                        self.last_price, vol)
        elif delta < -threshold and momentum <= -significant_diff:  ## bar 收盘价下穿ma均线,且偏离满足信号过滤条件
            # 没有多仓时,开空
            if (b_p is None or
                    b_p.volume < eps) and self.trade_count < self.trade_limit:
                vol = self.trade_unit[self.trade_count]
                self.trade_count += 1
                if vol > eps:
                    self.open_short(self.exchange, self.sec_id,
                                    self.last_price, vol)
            else:
                # 已有多仓,且达到了交易次数限制,平掉多仓
                if b_p and b_p.volume > eps and self.trade_count == self.trade_limit:
                    self.close_long(self.exchange, self.sec_id,
                                    self.last_price, b_p.volume)
                    self.trade_count = 0
                else:
                    # 已有多仓,且没有达到交易次数限制,继续加多
                    vol = self.trade_unit[
                        self.
                        trade_count] if self.trade_count < self.trade_limit else 0.0
                    self.trade_count += 1
                    if vol > eps:
                        self.open_long(self.exchange, self.sec_id,
                                       self.last_price, vol)
        else:  ##  其他情况,忽略不处理
            ## get positions and close if any
            #self.trade_count = 0   ## reset trade count
            pass
Ejemplo n.º 7
0
    def algo_action(self):
        close = np.asarray(self.close_buffer)
        if len(close) < self.life_timeperiod:
            self.logger.info('data not enough! len = {0}'.format(len(close)))
            return

        sma = SMA({'close': close}, timeperiod=self.short_timeperiod)
        lma = SMA(
            {'close': close},
            timeperiod=self.long_timeperiod)  ## make sure last lma is a number
        life = SMA({'close': close}, timeperiod=self.life_timeperiod)

        s_l_ma_delta = sma[-1] - lma[-1]  ## 最新的短长MA差值
        last_ma = sma[-1]  ## 最新的短MA

        #momentum = self.momentum = sma[-1] - sma[-2]  ## MA冲量
        momentum = self.momentum = self.last_price - sma[-1]  ## 当前价格相对MA冲量

        ## 短MA变动趋势,true表示进入趋势,false表示震荡
        moving_long = self.moving_long = moving_short = self.moving_short = False

        sma_diff = sma[-1] - sma[-2]
        sma_diff_1 = sma[-2] - sma[-3]
        moving = self.moving = sma_diff * sma_diff_1 > 0
        if moving and (sma_diff * momentum > 0
                       or momentum >= self.momentum_factor * s_l_ma_delta):
            moving_long = self.moving_long = True
        elif moving and (sma_diff * momentum > 0
                         or momentum <= self.momentum_factor * s_l_ma_delta):
            moving_short = self.moving_short = True

        ## 均线是多头还是空头排列
        long_trends = self.long_trends = (sma[-1] > lma[-1] > life[-1])
        short_trends = self.short_trends = (sma[-1] < lma[-1] < life[-1])
        self.logger.info('short ma: {0}, long ma: {1}, life line: {2}'.format(
            round(sma[-1], 4), round(lma[-1], 4), round(life[-1], 4)))
        self.logger.info(
            'short long ma delta: {0}, last_ma: {1}, momentum: {2}'.format(
                round(s_l_ma_delta, 4), round(last_ma, 4), round(momentum, 4)))
        self.logger.info(
            '## short ma moving long: {0}, moving short: {1}; Trends is long: {2}, is short: {3}.'
            .format(moving_long, moving_short, long_trends, short_trends))

        if self.analyse_only:
            return

        ## 下单基准价,为了能够成交,所有开平仓都会根据配置的跳数追价,这里先计算基准价格
        price_base = max(self.last_price, close[-1]) if long_trends else (min(
            self.last_price, close[-1]) if short_trends else self.last_price)

        self.logger.info("current trade count = {0}, price base = {1} ".format(
            self.trade_count, round(price_base, 1)))

        self.care_positions()
        b_p = self.b_p

        # cancel unfinished orders
        #self.cancel_unfinished_orders()

        threshold = self.threshold
        significant_diff = self.significant_diff
        stop_lose_threshold = self.stop_lose_threshold
        stop_profit_threshold = self.stop_profit_threshold

        ## 多信号
        if long_trends:  ## short ma cross up long ma
            ## 没有多仓
            if (b_p is None or b_p.volume < eps):
                signal_filter = (
                    moving_long or momentum >= significant_diff
                ) and s_l_ma_delta > threshold and self.trade_count < self.trade_limit
                vol = self.trade_unit[
                    self.trade_count]  ## get order volume from configured list
                if signal_filter and vol > eps:
                    self.trade_count += 1
                    ord_price = price_base + self.hops * self.tick_size
                    self.logger.info(
                        "open long ... count {0}, {1} @ {2}".format(
                            self.trade_count, vol, ord_price))
                    self.open_long(self.exchange, self.sec_id, ord_price, vol)
            ## 有多仓,且有止赢要求
            elif b_p and b_p.volume > eps:
                checking_limit = self.trade_count == self.trade_limit  ## 最大交易次数限制止赢
                b_pnl = self.last_price - b_p.vwap  ## 多仓浮赢
                if self.positive_stop and (checking_limit
                                           or b_pnl >= stop_profit_threshold):
                    ord_price = price_base - self.hops * self.tick_size
                    self.logger.info(
                        "trade count {0} to limit time[{1}], stop profit, close long @ {2}"
                        .format(self.trade_count, self.trade_limit, ord_price))
                    self.close_long_positions(b_p, ord_price)
                    self.trade_count = 0
                elif moving_short:  ## 短线趋势反转,检查是否要riskoff
                    self.try_stop_action()
            else:
                pass

        ## 空信号
        elif short_trends:  ## short ma cross down long ma
            ## 有多仓
            if b_p and b_p.volume > eps:
                self.logger.info("trend changed, stop lose, close long")
                self.close_long_positions(b_p)
                self.trade_count = 0
            else:
                pass

        else:  ##  check if need to stop trading,  close all positions
            self.logger.info("no trends, here check if need to stop ...")
            self.try_stop_action()
Ejemplo n.º 8
0
from talib.abstract import SMA,EMA
import sys

# 登入帳號密碼(讀者須修正該帳號密碼為自己的,否則無法執行策略)
GOrder.Login('TestAccount','TestPasswd')
# 建立部位管理物件
OrderRecord=Record() 
# 取得回測參數、移動停損點數
StartDate=sys.argv[1]
EndDate=sys.argv[2]
LongMAPeriod=int(sys.argv[3])
ShortMAPeriod=int(sys.argv[4])
MoveStopLoss=float(sys.argv[5])
# 回測取報價物件
KBar=GOrder.GetTAKBar(StartDate,EndDate,'3008','Stock','0','5')
KBar['MA_long']=SMA(KBar,timeperiod=LongMAPeriod)
KBar['MA_short']=EMA(KBar,timeperiod=ShortMAPeriod)
# 開始回測
for n in range(0,len(KBar['time'])-1):
    # 先判斷long MA的上一筆值是否為空值 再接續判斷策略內容
    if not np.isnan( KBar['MA_long'][n-1] ) :
        # 如果無未平倉部位 
        if OrderRecord.GetOpenInterest()==0 :
            # short MA 向上突破 long MA
            if KBar['MA_short'][n-1] <= KBar['MA_long'][n-1] and KBar['MA_short'][n] > KBar['MA_long'][n] :
                OrderRecord.Order('Buy', KBar['product'][n+1],KBar['time'][n+1],KBar['open'][n+1],1)
                OrderPrice = KBar['open'][n+1]
                StopLossPoint = OrderPrice * (1 - MoveStopLoss)
                continue
            # short MA 向下突破 long MA
            if KBar['MA_short'][n-1] >= KBar['MA_long'][n-1] and KBar['MA_short'][n] < KBar['MA_long'][n] :
 def getSMA(self, period=50):
     try:
         return SMA(self.data, timeperiod=period)
     except:
         raise TALIB_CALC_ERROR("SMA Calculation Error")