Esempio n. 1
0
    def on_create(self):
        """
        决策初始化.
        """
        self.write_log("on_create")

        self.market = MarketImpl()
        self.market.addNotice(self.code)

        pass
Esempio n. 2
0
 def __init__(self, start: datetime, end: datetime, limit_size=-1):
     self.index = 0
     self.start = start
     self.end = end
     from earnmi.data.MarketImpl import MarketImpl
     self.market = MarketImpl()
     self.market.setToday(end + timedelta(days=1))
     self.limitSize = len(ZZ500DataSource.SZ500_JQ_CODE_LIST)
     if limit_size > 0:
         self.limitSize = min(limit_size, self.limitSize)
Esempio n. 3
0
    def on_create(self):
        """
        决策初始化.
        """
        self.market_open_count = 0
        self.market = MarketImpl()

        self.market.addNotice("601318")  ##工商银行

        if (not self.backtestContext is None):
            # 从网络上面准备数据。
            self.write_log(
                f"on_create from backtestEngine, start={self.backtestContext.start_date},end={self.backtestContext.end_date}"
            )
        else:
            self.write_log("on_create")
        pass
Esempio n. 4
0
    def showCompare(self, bars: [], code: str):
        from earnmi.data.MarketImpl import MarketImpl
        market = MarketImpl()
        market.addNotice(code)
        today: datetime = bars[-1].datetime
        market.setToday(today + timedelta(days=1))
        start: datetime = bars[0].datetime
        baseBars = market.getHistory().getKbarFrom(
            code, datetime(start.year, start.month, start.day))

        #baseBar = mainBar
        ### 初始化columns
        columns = ['Open', 'High', 'Low', 'Close', "Volume", "Close2"]
        data = []
        index = []
        bars1 = baseBars
        bars2 = bars
        size1 = len(bars1)
        size2 = len(bars2)
        rate = bars1[0].close_price / bars2[0].close_price
        bar_pre_2 = bars2[0]
        i2 = 0
        for i1 in range(size1):
            bar1 = bars1[i1]
            index.append(bar1.datetime)
            list = [
                bar1.open_price, bar1.high_price, bar1.low_price,
                bar1.close_price, bar1.volume
            ]

            if i2 < size2:
                bar2 = bars2[i2]
                if utils.is_same_day(bar1.datetime, bar2.datetime):
                    list.append(bar2.close_price * rate)
                    bar_pre_2 = bar2
                    i2 = i2 + 1
                else:
                    ##bar2缺少今天数据。
                    list.append(bar_pre_2.close_price * rate)
                ##保证i2要大于大
                while (i2 < size2):
                    bar2 = bars2[i2]
                    days = (bar2.datetime - bar1.datetime).days
                    if days > 0:
                        break
                    i2 = i2 + 1
            else:
                list.append(bar_pre_2.close_price * rate)
            data.append(list)

        trades = pd.DataFrame(data, index=index, columns=columns)
        apds = []
        apds.append(mpf.make_addplot(trades['Close'], color='gray'))
        apds.append(mpf.make_addplot(trades['Close2'], color='r'))
        mpf.plot(trades, type='line', figscale=1.3, addplot=apds)
        pass
Esempio n. 5
0
 def test():
     strategy = MyStrategy()
     pdData = runner.backtest(testDataSouce, strategy, min_deal_count=15)
     writer = pd.ExcelWriter('models\output.xlsx')
     pdData.to_excel(writer, sheet_name="data", index=False)
     writer.save()
     writer.close()
     import numpy as np
     countList = np.array(list(strategy.mDateHoldCountMap.values()))
     print(
         f"每天操作平均发生:{countList.mean()},最大:{countList.max()},最小:{countList.min()}"
     )
     countList = np.array(list(model.mDateOccurCountMap.values()))
     print(
         f"每个交易日平均发生:{countList.mean()},最大:{countList.max()},最小:{countList.min()}"
     )
     countList = countList + 1
     from vnpy.trader.constant import Exchange, Interval
     swBars = []
     for dt, count in model.mDateOccurCountMap.items():
         value = 1000 * (count + 1) / 89
         bar = BarData(symbol="sw_code",
                       exchange=Exchange.SZSE,
                       datetime=dt,
                       interval=Interval.DAILY,
                       volume=value,
                       open_price=value,
                       high_price=value,
                       low_price=value,
                       close_price=value,
                       open_interest=0,
                       gateway_name="DB")
         swBars.append(bar)
     bars = swBars
     code = "000300"
     from earnmi.data.MarketImpl import MarketImpl
     market = MarketImpl()
     market.addNotice(code)
     today: datetime = bars[-1].datetime
     market.setToday(today + timedelta(days=1))
     start: datetime = bars[0].datetime
     baseBars = market.getHistory().getKbarFrom(
         code, datetime(start.year, start.month, start.day))
     chart = Chart()
     #chart.show(swBars)
     chart.showCompare(swBars, "000300")
Esempio n. 6
0
class MomentStrategy(StockStrategy):
    def __init__(self):
        pass

    codes = [
        '600196',
        # '600211',
        # '600316',
        # '600764',
        # '600893',
        # '600988',
        # '600989',
        # '601216',
        # '601633',
        # '603737',
        # '600733',
        # '600738',
        # '600877',
        # '602025',
        # '602081',
        # '602151',
        # '602444',
        # '602506',
        # '602541',
        # '602625',
        # '602985',
        # '300123'
    ]

    def on_create(self):
        """
        决策初始化.
        """
        self.write_log("on_create")

        self.market = MarketImpl()
        for code in self.codes:
            self.market.addNotice(code)

        pass

    def on_destroy(self):
        """
            决策结束.(被停止之后)
        """
        self.write_log("on_destroy")
        pass

    """
    当 AroonUp大于AroonDown,并且AroonUp大于50,多头开仓;
    当 AroonUp小于AroonDown,或者AroonUp小于50,多头平仓;
    """

    def on_market_prepare_open(self, protfolio: Portfolio, today: datetime):
        """
            市场准备开始(比如:竞价).
        """
        indicator = Indicator(40)
        for code in self.codes:
            bars = self.market.getHistory().getKbars(code, 100)
            indicator.update_bar(bars)
            count = 20
            aroon_down, aroon_up = indicator.aroon(count)
            need_hold = aroon_up > 50 and aroon_up > aroon_down
            position = protfolio.getLongPosition(code)

            if need_hold:
                if position.pos_total < 1:
                    targetPrice = bars[-1].close_price * 1.05  # 上一个交易日的收盘价作为买如价
                    ok = protfolio.buyAtPercentage(code, targetPrice, 1)
                    print(f"buy: price = {targetPrice} , {ok}")

            else:
                if position.pos_total > 0:
                    targetPrice = bars[-1].close_price * 0.92  # 上一个交易日的收盘价作为买如价
                    ok = protfolio.sellAll(code, targetPrice)
                    print(f"sell: price = {targetPrice} , {ok}")

        pass

    def on_market_open(self, protfolio: Portfolio):
        """
            市场开市.
        """

    def on_market_prepare_close(self, protfolio: Portfolio):
        """
            市场准备关市.
        """

        pass

    def on_market_close(self, protfolio: Portfolio):
        """
            市场关市.
        """

        pass

    def on_bar_per_minute(self, time: datetime, protfolio: Portfolio):
        """
            市场开市后的每分钟。
        """
        pass
Esempio n. 7
0
class StrategyTest(StockStrategy):

    market_open_count = 0
    start_trade_time = None
    end_trade_time = None
    final_valid_capital = 0
    portfolio: Portfolio = None

    def __init__(self, ):
        pass

    def on_create(self):
        """
        决策初始化.
        """
        self.market_open_count = 0
        self.market = MarketImpl()

        self.market.addNotice("601318")  ##工商银行

        if (not self.backtestContext is None):
            # 从网络上面准备数据。
            self.write_log(
                f"on_create from backtestEngine, start={self.backtestContext.start_date},end={self.backtestContext.end_date}"
            )
        else:
            self.write_log("on_create")
        pass

    def on_destroy(self):
        """
            决策结束.(被停止之后)
        """
        self.write_log("on_destroy")
        pass

    daily_pre_tick: TickData = None

    def on_market_prepare_open(self, protfolio: Portfolio, toady: datetime):
        self.portfolio = protfolio
        """
            市场准备开始(比如:竞价).
        """
        assert is_same_day(toady, self.market.getToday())

        if (self.start_trade_time is None):
            self.start_trade_time = toady
        self.end_trade_time = toady

        self.daily_pre_tick = None

        pass

    def on_market_open(self, protfolio: Portfolio):
        """
            市场开市.
        """
        self.market_open_count = self.market_open_count + 1
        self.on_bar_per_minute_count = 0

        if (is_same_day(datetime(2019, 2, 23), self.market.getToday())):
            ###刚刚开始,没有任何持仓
            assert protfolio.sell("601318", 67.15, 100) == False
            assert protfolio.cover("601318", 67.15, 100) == False

        # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15
        # 中国平安601318 在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57
        # 中国平安601318 在datetime(2019, 2, 28)时刻,9点40分左右到最低点66.8,10:47最高到达68.08,然后14:00后面出现新的第二低点67.2-67.4

        self.daily_pre_tick = self.market.getRealTime().getTick("601318")

        if (is_same_day(datetime(2019, 2, 26, 10, 28),
                        self.market.getToday())):
            assert protfolio.buy("601318", 67.15, 100) == True
            assert protfolio.buy("601318", 67.15, 100) == False  ##钱不够
            assert protfolio.buy("601318", 67.15, 1) == True
            assert protfolio.buy("601318", 67.10,
                                 1) == True  ##价格过低,能委托成功,但没发成交
            assert protfolio.buy("601318", 66.10,
                                 1) == True  ##价格过低,能委托成功,但没发成交
            assert protfolio.buy("601318", 66.10,
                                 1) == True  ##价格过低,能委托成功,但没发成交

        if (is_same_day(datetime(2019, 2, 27, 9, 48), self.market.getToday())):
            position = protfolio.getLongPosition("601318")
            assert position.is_long == True
            assert position.pos_total == 121 * 100
            assert position.getPosAvailable() == 121 * 100  # 昨天买入的,所以今天可用

            assert protfolio.sell("601318", 68.54, 500) == False  ##持仓数不够
            assert protfolio.sell("601318", 68.54, 55) == True
            assert protfolio.sell("601318", 68.54, 46) == True

            assert protfolio.short(
                "601318", 68.54, 10
            ) == True  ###开始做空买入在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57
            assert protfolio.short("601318", 68.70,
                                   1) == True  ##价格过低,能委托成功,但没发成交

        if (is_same_day(datetime(2019, 2, 28, 10, 48),
                        self.market.getToday())):
            assert protfolio.buy("601318", 67.40, 120) == True

        # 4月23日,清空持仓
        if (is_same_day(datetime(2019, 4, 23), self.market.getToday())):
            longPos = protfolio.getLongPosition("601318")
            shortPos = protfolio.getShortPosition("601318")
            assert longPos.pos_lock == 0 and shortPos.pos_lock == 0  #这个时间是没有冻结的
            #high: 2019 - 04 - 23  13: 47:00: open = 83.77, close = 83.88
            #low: 2019 - 04 - 23  09: 31:00: open = 81.38, close = 81.35
            protfolio.cover("601318", 83.77, shortPos.pos_total / 100)
            protfolio.sell("601318", 81.35, longPos.pos_total / 100)

        pass

    def on_market_prepare_close(self, protfolio: Portfolio):
        """
            市场准备关市.
        """
        time = self.market.getToday()
        assert time.hour == 14 and time.minute == 57

        # 最开始datetime(2019, 2, 26, 10, 28)买入100股,由于A股T+1的限制,是不可以当天卖的
        if (utils.is_same_day(datetime(2019, 2, 26, 10, 28), time)):
            assert protfolio.sell("601318", 67.00, 100) == False

        pass

    def on_market_close(self, protfolio: Portfolio):
        """
            市场关市.
        """
        time = self.market.getToday()
        assert time.hour == 15 and time.minute == 0

        assert self.on_bar_per_minute_count > 200

        self.final_valid_capital = protfolio.getValidCapital()

        # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15
        if utils.is_same_day(datetime(2019, 2, 26), self.market.getToday()):
            #当天已经买入121*100股,持有仓位资金不为0
            assert protfolio.getTotalHoldCapital() > 810700
            position = protfolio.getLongPosition("601318")
            assert position.is_long == True
            assert position.pos_total == 121 * 100
            assert position.getPosAvailable() == 0  # 因为今天才交易,可用仓位为0
        pass

    sell_time_01_tag = False

    def on_bar_per_minute(self, time: datetime, protfolio: Portfolio):
        """
            市场开市后的每分钟。
        """
        self.on_bar_per_minute_count = self.on_bar_per_minute_count + 1

        assert is_same_minitue(time, self.market.getToday())
        assert time.hour >= 9  #9点后开市
        if (time.hour > 9 or (time.hour == 9 and time.minute > 32)):
            ##开市之后的实时信息不应该为none
            bar = self.market.getRealTime().getKBar("601318")
            assert not bar is None

            tickData: BarData = self.market.getRealTime().getTick("601318")
            preTickData: BarData = self.daily_pre_tick

            assert not tickData is None
            assert not preTickData is None
            deltaFloat = preTickData.close_price * 0.015
            assert utils.isEqualFloat(preTickData.close_price,
                                      tickData.open_price, deltaFloat)

        self.daily_pre_tick = self.market.getRealTime().getTick("601318")

        # 中国平安601318
        # 2019-03-25 10:35:00:open = 71.03,close=70.96 一天最高点
        # 2019-03-25 13:12:00:open = 69.97,close=69.79  下午开盘的一个低点
        # 2019-03-25 13:47:00:open = 70.33,close=70.41   下午的一个高点
        sell_time_01 = datetime(2019, 3, 25, 13, 12)
        if not self.sell_time_01_tag:
            if (utils.is_same_minitue(sell_time_01, time)):
                protfolio.sell("601318", 70.35, 120)
                self.sell_time_01_tag = True

        #self.write_log(f"     on_bar_per_minute:{time}" )
        # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15
        if (utils.is_same_time(datetime(2019, 2, 26, 10, 28),
                               self.market.getToday(),
                               deltaSecond=30)):
            protfolio.buy("601318", 70.75, 20)  ##测试交割价格在67.15附近

        # 中国平安601318 在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57
        if (utils.is_same_time(datetime(2019, 2, 27, 9, 48),
                               self.market.getToday(),
                               deltaSecond=30)):
            protfolio.sell("601318", 60.75, 20)  ##测试交割价格在68.57附近

        ###开始做空买入在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57
        # 中国平安601318 在datetime(2019, 2, 28)时刻,9点40分左右到最低点66.8,10:47最高到达68.08,然后14:00后面出现新的第二低点67.2-67.4
        if (utils.is_same_time(datetime(2019, 2, 28, 11, 00),
                               self.market.getToday(),
                               deltaSecond=30)):
            assert protfolio.cover("601318", 67.3,
                                   10) == True  ## 11点后开始平仓,以当天第二低价格平仓

        # 4月1日 - 20日随机交易
        today = self.market.getToday()
        #today >= datetime(2019,3,2,0) and today <= datetime(2019,3,20,0) or
        # if  today >= datetime(2019,4,1,0) and today <= datetime(2019,4,20,0):
        #     happen = random.random()
        #     if happen <= 0.1:
        #         self.__randomTrade(protfolio)

    def __randomTrade(self, protfolio: Portfolio):
        happen = random.random()
        code = "601318"
        price = self.market.getRealTime().getTick(code).close_price
        trade_price = price * random.uniform(0.94, 1.06)
        volume = random.randint(3, 100)
        if happen <= 0.25:
            protfolio.buy(code, trade_price, volume)
        elif happen <= 0.5:
            protfolio.sell(code, trade_price, volume)
        elif happen <= 0.75:
            protfolio.short(code, trade_price, volume)
        else:
            protfolio.cover(code, trade_price, volume)

    def on_order(self, order: OrderData):
        print(f"{self.market.getToday()}:onOrder: {order}")

    sell_at_2019_2_27_9_48 = False
    buy_at_2019_2_26_10_28 = 0
    sell_at_2019_3_25_13_47 = False
    short_at_2019_2_27_9_48 = False
    cover_at_2019_2_28_14_more = False

    def on_trade(self, trade: TradeData):
        print(f"{self.market.getToday()}:on_trade: {trade}")
        # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15,到达买入价
        # 中国平安601318 在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57,到达卖出价
        # 中国平安601318 在datetime(2019, 3, 25, 13, 10)时刻,从最高价71到一个新底69.75, 后面再到一个新的高点。7.38左右
        # 中国平安601318 在datetime(2019, 2, 28)时刻,9点40分左右到最低点66.8,10:47最高到达68.08,然后14:00后面出现新的第二低点67.2-67.4

        is_buy = trade.direction == Direction.LONG and trade.offset == Offset.OPEN
        is_sell = trade.direction == Direction.SHORT and trade.offset == Offset.CLOSE
        is_short = trade.direction == Direction.SHORT and trade.offset == Offset.OPEN
        is_cover = trade.direction == Direction.LONG and trade.offset == Offset.CLOSE

        if (utils.is_same_time(datetime(2019, 2, 26, 10, 28),
                               self.market.getToday(),
                               deltaSecond=30)):
            if is_buy:
                self.buy_at_2019_2_26_10_28 = self.buy_at_2019_2_26_10_28 + 1
                assert utils.isEqualFloat(67.15, trade.price,
                                          0.5)  #成交价格在67.15中间

        if (utils.is_same_day(datetime(2019, 2, 28), self.market.getToday())):
            if is_cover:
                assert self.cover_at_2019_2_28_14_more == False
                self.cover_at_2019_2_28_14_more = True
                assert utils.isEqualFloat(67.3, trade.price,
                                          0.5)  #成交价格在67.15中间

        if (utils.is_same_time(self.market.getToday(),
                               datetime(2019, 2, 27, 9, 48),
                               deltaMinitue=1,
                               deltaSecond=2)):
            if is_sell:
                self.sell_at_2019_2_27_9_48 = True
                assert utils.isEqualFloat(68.57, trade.price,
                                          0.5)  # 成交价格在68.57中间
            if is_short:
                self.short_at_2019_2_27_9_48 = True
                assert utils.isEqualFloat(68.57, trade.price,
                                          0.5)  # 成交价格在68.57中间

        # 中国平安601318
        # 2019-03-25 10:35:00:open = 71.03,close=70.96 一天最高点
        # 2019-03-25 13:12:00:open = 69.97,close=69.79  下午开盘的一个低点
        # 2019-03-25 13:47:00:open = 70.33,close=70.41   下午的一个高点
        if (utils.is_same_time(self.market.getToday(),
                               datetime(2019, 3, 25, 13, 47),
                               deltaMinitue=4,
                               deltaSecond=2)):
            if is_sell:
                self.sell_at_2019_3_25_13_47 = True
                assert utils.isEqualFloat(70.36, trade.price,
                                          0.5)  # 成交价格在68.57中间

    def on_stop_order(self, stop_order: StopOrder):
        print(f"{self.market.getToday()}:on_stop_order: {stop_order}")
Esempio n. 8
0
            values["arron_up_25"] = 50
            values["arron_down_25"] = 50

        return values

    def getColor(self, name: str):
        if name == "arron_up_25":
            return 'r'
        return 'y'

    def isLowerPanel(self):
        return True


if __name__ == "__main__":
    from earnmi.data.MarketImpl import MarketImpl

    code = "600155"
    # 801161.XSHG
    market = MarketImpl()
    market.addNotice(code)
    market.setToday(datetime.now())

    bars = market.getHistory().getKbars(code, 360)

    print(f"bar.size = {bars.__len__()}")

    chart = Chart()
    #chart.open_kdj = True
    #chart.show(bars,KDJItem())
    chart.showCompare(bars, "000300")
Esempio n. 9
0
from datetime import datetime, timedelta
from earnmi.chart.Chart import Chart
from earnmi.data.Market import Market
from earnmi.data.MarketImpl import MarketImpl
from vnpy.trader.constant import Interval, Exchange
from vnpy.trader.database import database_manager
from earnmi.data import import_data_from_jqdata

def assertEqual(d1, d2):
    if( not d1.__eq__(d2)):
        raise AssertionError(f"asset fail!,d1={d1},d2={d2}")

def assertLittle(d1, d2):
    if (not d1.__le__(d2)):
        raise AssertionError(f"asset fail!,d1={d1},d2={d2}")

code = "000300"
startDate = datetime(2019,4,1)
endDate = datetime(2020,5,1)
today = datetime(2020,3,24)
keepN = 88

market = MarketImpl()

market.addNotice(code)
market.setToday(today)




Esempio n. 10
0
from datetime import datetime

from earnmi.data.MarketImpl import MarketImpl
from earnmi.data.SWImpl import SWImpl
import time

sw = SWImpl()

swCode = sw.getSW2List()[0]

stockslist = sw.getSW2Stocks(swCode)

print(f"stockslist:{len(stockslist)}")

startDate = datetime(2015, 4, 1)
endDate = datetime(2020, 5, 1)
market = MarketImpl()
market.setToday(endDate)

market.addNotice('002852')
bars = market.getHistory().getKbars('002852', 300 * 3)

for code in stockslist:
    market.addNotice(code)
    print(f"getBars:{code}")
    bars = market.getHistory().getKbars(code, 300 * 3)
    #time.sleep(2)

    print(f"getBars size:{len(bars)}")
Esempio n. 11
0
class macd(StockStrategy):

    def __init__(self):
       pass
    codes = ["300004"]

    activity_long_dict:Dict[str,Long_Item] = {}
    activity_short_dict:Dict[str,Short_Item] = {}
    long_datas:Sequence["Long_Item"] = []
    short_datas:Sequence["Short_Item"] = []


    def on_create(self):
        """
        决策初始化.
        """
        self.write_log("on_create")

        self.market = MarketImpl()
        for code in self.codes:
            self.market.addNotice(code)

        pass

    def on_destroy(self):
        """
            决策结束.(被停止之后)
        """
        self.write_log("on_destroy")
        pass

    def on_market_prepare_open(self,protfolio:Portfolio,today:datetime):
        """
            市场准备开始(比如:竞价).
        """
        indicator = Indicator(40)
        for code in self.codes:
            bars = self.market.getHistory().getKbars(code, 100);
            indicator.update_bar(bars)
            dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True);

                ##金叉出现
            if (macd_bar[-1] >= 0 and macd_bar[-2] <= 0):
                tradePrice = bars[-1].close_price * 1.01  # 上一个交易日的收盘价作为买如价
                protfolio.buy(code, tradePrice, 1)
                protfolio.cover(code,tradePrice,1)  ##平仓做空
                ##死叉出现
            if (macd_bar[-1] <= 0 and macd_bar[-2] >=0):
                targetPrice = bars[-1].close_price * 0.99  # 上一个交易日的收盘价作为买如价
                protfolio.sell(code, targetPrice, 1)
                protfolio.short(code, targetPrice, 1)  ##开仓做空



        pass

    def on_trade(self, trade: TradeData):
        is_buy = trade.direction == Direction.LONG and trade.offset == Offset.OPEN
        is_sell = trade.direction == Direction.SHORT and trade.offset == Offset.CLOSE
        is_short = trade.direction == Direction.SHORT and trade.offset == Offset.OPEN
        is_cover = trade.direction == Direction.LONG and trade.offset == Offset.CLOSE

        today = self.market.getToday()
        if is_buy:
            long_data = Long_Item(symbol=trade.symbol,start_time=today,start_price=trade.price)
            self.activity_long_dict[trade.symbol] = long_data
            self.__update_long_max_price(trade.symbol,trade.price)
        elif is_sell:
            self.__update_long_max_price(trade.symbol,trade.price)
            long_data = self.activity_long_dict.get(trade.symbol)
            if not long_data is None:
                long_data.end_time = today
                long_data.end_price = trade.price
                long_data.duration_days = (today - long_data.start_time).days
                self.long_datas.append(long_data)
                del self.activity_long_dict[trade.symbol]
        elif is_short:
            short_data = Short_Item(symbol=trade.symbol, start_time=today, start_price=trade.price)
            self.activity_short_dict[trade.symbol] = short_data
            self.__update_short_min_price(trade.symbol,trade.price)

        elif is_cover:
            self.__update_short_min_price(trade.symbol,trade.price)
            short_data = self.activity_short_dict.get(trade.symbol)
            if not short_data is None:
                short_data.end_time = today
                short_data.end_price = trade.price
                short_data.duration_days = (today - short_data.start_time).days
                self.short_datas.append(short_data)
                del self.activity_short_dict[trade.symbol]

    def __update_long_max_price(self,code:str,max_price:float):
        data_item = self.activity_long_dict.get(code)
        if data_item is None:
            return
        today = self.market.getToday()
        delta_day = (today - data_item.start_time).days
        if max_price > data_item.max_price:
            data_item.max_price = max_price
            data_item.max_price_time = today
            data_item.max_price_day = delta_day
            delta_pnl = (data_item.max_price - data_item.start_price) / data_item.start_price
            if (delta_pnl >= 0.03 and data_item.max_pnl_3_day < 0):
                data_item.max_pnl_3_day = delta_day

            if (delta_pnl >= 0.05 and data_item.max_pnl_5_day < 0):
                data_item.max_pnl_5_day = delta_day

            if (delta_pnl >= 0.07 and data_item.max_pnl_7_day < 0):
                data_item.max_pnl_7_day = delta_day

            if (delta_pnl >= 0.09 and data_item.max_pnl_9_day < 0):
                data_item.max_pnl_9_day = delta_day

            if (delta_pnl >= 0.11 and data_item.max_pnl_11_day < 0):
                data_item.max_pnl_11_day = delta_day

            if (delta_pnl >= 0.13 and data_item.max_pnl_13_day < 0):
                data_item.max_pnl_13_day = delta_day

            if (delta_pnl >= 0.15 and data_item.max_pnl_15_day < 0):
                data_item.max_pnl_15_day = delta_day

            if (delta_pnl >= 0.17 and data_item.max_pnl_17_day < 0):
                data_item.max_pnl_17_day = delta_day

            if (delta_pnl >= 0.19 and data_item.max_pnl_19_day < 0):
                data_item.max_pnl_19_day = delta_day

            if (delta_pnl >= 0.21 and data_item.max_pnl_21_more_day < 0):
                data_item.max_pnl_21_more_day = delta_day

    def __update_short_min_price(self, code:str, min_price:float):
        data_item:Short_Item = self.activity_short_dict.get(code)
        if data_item is None:
            return
        today = self.market.getToday()
        delta_day = (today - data_item.start_time).days
        if min_price < data_item.min_price:
            data_item.min_price = min_price
            data_item.min_price_time = today
            data_item.min_price_day = delta_day
            delta_pnl = (data_item.min_price - data_item.start_price) / data_item.start_price
            if (delta_pnl >= 0.03 and data_item.min_pnl_3_day < 0):
                data_item.min_pnl_3_day = delta_day

            if (delta_pnl >= 0.05 and data_item.min_pnl_5_day < 0):
                data_item.min_pnl_5_day = delta_day

            if (delta_pnl >= 0.07 and data_item.min_pnl_7_day < 0):
                data_item.min_pnl_7_day = delta_day

            if (delta_pnl >= 0.09 and data_item.min_pnl_9_day < 0):
                data_item.min_pnl_9_day = delta_day

            if (delta_pnl >= 0.11 and data_item.min_pnl_11_day < 0):
                data_item.min_pnl_11_day = delta_day

            if (delta_pnl >= 0.13 and data_item.min_pnl_13_day < 0):
                data_item.min_pnl_13_day = delta_day

            if (delta_pnl >= 0.15 and data_item.min_pnl_15_day < 0):
                data_item.min_pnl_15_day = delta_day

            if (delta_pnl >= 0.17 and data_item.min_pnl_17_day < 0):
                data_item.min_pnl_17_day = delta_day

            if (delta_pnl >= 0.19 and data_item.min_pnl_19_day < 0):
                data_item.min_pnl_19_day = delta_day

            if (delta_pnl >= 0.21 and data_item.min_pnl_21_more_day < 0):
                data_item.min_pnl_21_more_day = delta_day



    def on_market_open(self,protfolio:Portfolio):
        """
            市场开市.
        """



    def on_market_prepare_close(self,protfolio:Portfolio):
        """
            市场准备关市.
        """

        pass

    def on_market_close(self, protfolio:Portfolio):
        """
            市场关市.
        """
        for code in self.codes:
            bar  = self.market.getRealTime().getKBar(code)
            self.__update_long_max_price(code,bar.high_price)
            self.__update_short_min_price(code,bar.low_price)

        pass

    def on_bar_per_minute(self, time: datetime, protfolio:Portfolio):
        """
            市场开市后的每分钟。
        """
        pass
Esempio n. 12
0
class Strategy1(StockStrategy):
    def __init__(self):
        pass

    code = "300004"
    window_size = 30

    def on_create(self):
        """
        决策初始化.
        """
        self.write_log("on_create")

        self.market = MarketImpl()
        self.market.addNotice(self.code)

        pass

    def on_destroy(self):
        """
            决策结束.(被停止之后)
        """
        self.write_log("on_destroy")
        pass

    def on_market_prepare_open(self, protfolio: Portfolio, today: datetime):
        """
            市场准备开始(比如:竞价).
        """
        #准备线程池,准备数据。
        self.market.setToday(today)
        self.today_has_buy = False
        self.today_has_sell = False

        pass

    __history_bar100 = None

    def on_market_open(self, protfolio: Portfolio):
        """
            市场开市.
        """

    def on_market_prepare_close(self, protfolio: Portfolio):
        """
            市场准备关市.
        """

        pass

    def on_market_close(self, protfolio: Portfolio):
        """
            市场关市.
        """

        pass

    def on_bar_per_minute(self, time: datetime, protfolio: Portfolio):
        """
            市场开市后的每分钟。
        """
        #每天两点半的后尝试去做交易。
        if time.hour == 14 and time.minute == 30:
            self.__history_bar100 = self.market.getHistory().getKbars(
                self.code, 100)
            assert len(self.__history_bar100) == 100
            bars = self.__history_bar100

            todayBar = self.market.getRealTime().getKBar(self.code)

            indicator = Indicator(40)
            indicator.update_bar(bars)
            dif, dea, macd_bar = indicator.macd(fast_period=12,
                                                slow_period=26,
                                                signal_period=9,
                                                array=True)

            if (not self.today_has_buy):
                # 预测金叉
                todayBar.close_price = todayBar.close_price * 1.01
                indicator.update_bar(todayBar)
                dif, dea, predict_macd_bar = indicator.macd(fast_period=12,
                                                            slow_period=26,
                                                            signal_period=9,
                                                            array=True)
                print(
                    f"[{self.market.getToday()}]:bar={macd_bar[-1]},predic_bar={predict_macd_bar[-1]}"
                )

                if (predict_macd_bar[-1] > 0 and macd_bar[-1] <= 0):
                    targetPrice = todayBar.close_price  # 上一个交易日的收盘价作为买如价
                    print(f"   gold cross!!!")
                    if protfolio.buy(self.code, targetPrice, 100):
                        self.today_has_buy = True
            elif (not self.today_has_sell):
                todayBar.close_price = todayBar.close_price * 0.99
                indicator.update_bar(todayBar)
                dif, dea, predict_macd_bar = indicator.macd(fast_period=12,
                                                            slow_period=26,
                                                            signal_period=9,
                                                            array=True)
                print(
                    f"[{self.market.getToday()}]:bar={macd_bar[-1]},predic_bar={predict_macd_bar[-1]}"
                )
                if (predict_macd_bar[-1] <= 0 and macd_bar[-1] > 0):
                    targetPrice = todayBar.close_price
                    print(f"   dead cross!!!")
                    if protfolio.sell(self.code, targetPrice, 100):
                        self.today_has_sell = True
Esempio n. 13
0
def realTimeTest():
    market2 = MarketImpl()
    code = "300004"
    market2.addNotice(code)

    has_data_day1 = datetime(year=2020, month=5, day=8, hour=1)
    market2.setToday(has_data_day1)
    bar = market2.getRealTime().getKBar(code)
    assert bar is None

    market2.setToday(
        datetime(year=2020, month=5, day=8, hour=9, minute=31, second=30))
    bar = market2.getRealTime().getKBar(code)
    assert not bar is None
    bar = market2.getRealTime().getKBar(code, hour=9, minute=31, second=31)
    assert bar is None

    begin = datetime(year=2020, month=4, day=9, hour=1)
    for i in range(50):
        day = begin + timedelta(days=i)
        market2.setToday(
            datetime(year=day.year,
                     month=day.month,
                     day=day.day,
                     hour=9,
                     minute=50,
                     second=30))

        bar = market2.getRealTime().getKBar(code)
        todayIsTrade = not bar is None

        if todayIsTrade:

            print(f"realTimeTest:test in trad day : {day}")
            """
            今天是交易日
            """
            day1 = datetime(year=day.year,
                            month=day.month,
                            day=day.day,
                            hour=9,
                            minute=31,
                            second=30)
            day2 = datetime(year=day.year,
                            month=day.month,
                            day=day.day,
                            hour=10,
                            minute=31,
                            second=30)
            day3 = datetime(year=day.year,
                            month=day.month,
                            day=day.day,
                            hour=13,
                            minute=50,
                            second=30)
            day4 = datetime(year=day.year,
                            month=day.month,
                            day=day.day,
                            hour=15,
                            minute=0,
                            second=30)

            market2.setToday(day1)
            bar1 = market2.getRealTime().getKBar(code)

            market2.setToday(day2)
            bar2 = market2.getRealTime().getKBar(code)

            market2.setToday(day3)
            bar3 = market2.getRealTime().getKBar(code)

            market2.setToday(day4)
            bar4 = market2.getRealTime().getKBar(code)

            assert is_same_day(bar1.datetime, bar2.datetime) and is_same_day(
                bar3.datetime, bar4.datetime) and is_same_day(
                    bar2.datetime, bar3.datetime)
            assert bar1.datetime < bar2.datetime and bar2.datetime < bar3.datetime and bar3.datetime < bar4.datetime
            assert isPostMinitueBar(bar1, bar2) and isPostMinitueBar(
                bar2, bar3) and isPostMinitueBar(
                    bar3, bar4) and isPostMinitueBar(bar2, bar4)
Esempio n. 14
0
def basicTest():
    market2 = MarketImpl()
    code = "300004"
    assert market2.isNotice(code) == False

    market2.addNotice(code)
    assert market2.isNotice(code) == True
    key1 = market2.getNoticeData(code, "key1")
    assert key1 is None
    market2.putNoticeData(code, "key1", "hello")
    key1 = market2.getNoticeData(code, "key1")
    assert key1 == "hello"

    market2.removeNotice(code)
    assert market2.isNotice(code) == False
    try:
        key1 = market2.getNoticeData(code, "key1")
        assert False
    except RuntimeError:
        assert True
Esempio n. 15
0
def historyTest():
    market2 = MarketImpl()
    market2.setToday(datetime.now())

    #获取沪市数据
    code = "600000"
    market2.addNotice(code)
    bars = market2.getHistory().getKbars(code, 20)
    assert len(bars) == 20

    ##获取指数数据
    codes = ['000300']
    for code in codes:
        market2.addNotice(code)
        assert len(market2.getHistory().getKbars(code, 20)) == 20

    code = "300004"

    market2.addNotice(code)

    todayListBar = market2.getHistory().getKbars(code, 50)

    pre_bares = None
    for todayBar in todayListBar:
        today = datetime(year=todayBar.datetime.year,
                         month=todayBar.datetime.month,
                         day=todayBar.datetime.day,
                         minute=1)
        market2.setToday(today)
        bars1 = market2.getHistory().getKbars(code, 100)

        ##最后一个bar不应该包含今天:
        assert not utils.is_same_day(bars1[-1].datetime, today)

        assert len(bars1) == 100
        pre_bar = None
        for bar in bars1:
            assert bar.datetime < today
            if pre_bar:
                assert pre_bar.datetime < bar.datetime
            pre_bar = bar

        bars2 = market2.getHistory().getKbarFrom(code, bars1[0].datetime)
        for index in range(len(bars1)):
            assert bars1[index].datetime == bars2[index].datetime

        #昨天的bar数据
        if pre_bares:
            for index in range(len(pre_bares) - 1):
                assert pre_bares[index + 1].datetime == bars1[index].datetime

        pre_bares = bars1

    pass
Esempio n. 16
0
class ZZ500DataSource(BarDataSource):

    #中证500的股票列表,过滤掉最近2年新上市的,jq模式的代码,总共485个
    SZ500_JQ_CODE_LIST = [
        '000008.XSHE', '000009.XSHE', '000012.XSHE', '000021.XSHE',
        '000025.XSHE', '000027.XSHE', '000028.XSHE', '000031.XSHE',
        '000039.XSHE', '000046.XSHE', '000050.XSHE', '000060.XSHE',
        '000061.XSHE', '000062.XSHE', '000078.XSHE', '000089.XSHE',
        '000090.XSHE', '000156.XSHE', '000158.XSHE', '000301.XSHE',
        '000400.XSHE', '000401.XSHE', '000402.XSHE', '000415.XSHE',
        '000488.XSHE', '000501.XSHE', '000513.XSHE', '000519.XSHE',
        '000528.XSHE', '000537.XSHE', '000543.XSHE', '000547.XSHE',
        '000553.XSHE', '000559.XSHE', '000563.XSHE', '000564.XSHE',
        '000581.XSHE', '000598.XSHE', '000600.XSHE', '000623.XSHE',
        '000629.XSHE', '000630.XSHE', '000636.XSHE', '000681.XSHE',
        '000685.XSHE', '000686.XSHE', '000690.XSHE', '000712.XSHE',
        '000717.XSHE', '000718.XSHE', '000729.XSHE', '000732.XSHE',
        '000738.XSHE', '000739.XSHE', '000750.XSHE', '000758.XSHE',
        '000778.XSHE', '000785.XSHE', '000800.XSHE', '000807.XSHE',
        '000813.XSHE', '000825.XSHE', '000826.XSHE', '000830.XSHE',
        '000848.XSHE', '000869.XSHE', '000877.XSHE', '000878.XSHE',
        '000883.XSHE', '000887.XSHE', '000898.XSHE', '000930.XSHE',
        '000932.XSHE', '000937.XSHE', '000959.XSHE', '000960.XSHE',
        '000967.XSHE', '000970.XSHE', '000975.XSHE', '000983.XSHE',
        '000987.XSHE', '000988.XSHE', '000990.XSHE', '000997.XSHE',
        '000998.XSHE', '000999.XSHE', '001872.XSHE', '001914.XSHE',
        '002002.XSHE', '002004.XSHE', '002010.XSHE', '002013.XSHE',
        '002019.XSHE', '002028.XSHE', '002030.XSHE', '002038.XSHE',
        '002048.XSHE', '002051.XSHE', '002056.XSHE', '002064.XSHE',
        '002074.XSHE', '002075.XSHE', '002078.XSHE', '002080.XSHE',
        '002081.XSHE', '002085.XSHE', '002092.XSHE', '002093.XSHE',
        '002110.XSHE', '002118.XSHE', '002124.XSHE', '002127.XSHE',
        '002128.XSHE', '002131.XSHE', '002138.XSHE', '002152.XSHE',
        '002155.XSHE', '002156.XSHE', '002174.XSHE', '002183.XSHE',
        '002185.XSHE', '002191.XSHE', '002195.XSHE', '002203.XSHE',
        '002212.XSHE', '002217.XSHE', '002221.XSHE', '002223.XSHE',
        '002233.XSHE', '002242.XSHE', '002244.XSHE', '002249.XSHE',
        '002250.XSHE', '002266.XSHE', '002268.XSHE', '002273.XSHE',
        '002281.XSHE', '002285.XSHE', '002294.XSHE', '002302.XSHE',
        '002317.XSHE', '002340.XSHE', '002353.XSHE', '002368.XSHE',
        '002372.XSHE', '002373.XSHE', '002375.XSHE', '002382.XSHE',
        '002385.XSHE', '002387.XSHE', '002390.XSHE', '002396.XSHE',
        '002399.XSHE', '002407.XSHE', '002408.XSHE', '002414.XSHE',
        '002416.XSHE', '002419.XSHE', '002423.XSHE', '002424.XSHE',
        '002429.XSHE', '002434.XSHE', '002439.XSHE', '002440.XSHE',
        '002444.XSHE', '002458.XSHE', '002465.XSHE', '002491.XSHE',
        '002500.XSHE', '002503.XSHE', '002505.XSHE', '002506.XSHE',
        '002507.XSHE', '002511.XSHE', '002544.XSHE', '002557.XSHE',
        '002563.XSHE', '002572.XSHE', '002583.XSHE', '002589.XSHE',
        '002595.XSHE', '002603.XSHE', '002625.XSHE', '002635.XSHE',
        '002640.XSHE', '002648.XSHE', '002653.XSHE', '002665.XSHE',
        '002670.XSHE', '002690.XSHE', '002701.XSHE', '002709.XSHE',
        '002745.XSHE', '002797.XSHE', '002807.XSHE', '002815.XSHE',
        '002818.XSHE', '002821.XSHE', '002831.XSHE', '002839.XSHE',
        '002867.XSHE', '002901.XSHE', '002920.XSHE', '002925.XSHE',
        '002926.XSHE', '002936.XSHE', '300001.XSHE', '300002.XSHE',
        '300009.XSHE', '300010.XSHE', '300012.XSHE', '300017.XSHE',
        '300024.XSHE', '300026.XSHE', '300058.XSHE', '300070.XSHE',
        '300072.XSHE', '300088.XSHE', '300113.XSHE', '300115.XSHE',
        '300133.XSHE', '300134.XSHE', '300166.XSHE', '300168.XSHE',
        '300180.XSHE', '300182.XSHE', '300197.XSHE', '300207.XSHE',
        '300212.XSHE', '300244.XSHE', '300251.XSHE', '300253.XSHE',
        '300257.XSHE', '300271.XSHE', '300274.XSHE', '300285.XSHE',
        '300296.XSHE', '300315.XSHE', '300316.XSHE', '300324.XSHE',
        '300357.XSHE', '300376.XSHE', '300418.XSHE', '300459.XSHE',
        '300474.XSHE', '300482.XSHE', '300496.XSHE', '300558.XSHE',
        '300595.XSHE', '300618.XSHE', '300630.XSHE', '600006.XSHG',
        '600008.XSHG', '600017.XSHG', '600021.XSHG', '600022.XSHG',
        '600026.XSHG', '600037.XSHG', '600039.XSHG', '600053.XSHG',
        '600056.XSHG', '600058.XSHG', '600060.XSHG', '600062.XSHG',
        '600064.XSHG', '600073.XSHG', '600079.XSHG', '600094.XSHG',
        '600120.XSHG', '600125.XSHG', '600126.XSHG', '600132.XSHG',
        '600138.XSHG', '600141.XSHG', '600143.XSHG', '600153.XSHG',
        '600155.XSHG', '600158.XSHG', '600160.XSHG', '600161.XSHG',
        '600166.XSHG', '600167.XSHG', '600171.XSHG', '600195.XSHG',
        '600201.XSHG', '600216.XSHG', '600256.XSHG', '600258.XSHG',
        '600259.XSHG', '600260.XSHG', '600266.XSHG', '600273.XSHG',
        '600277.XSHG', '600282.XSHG', '600291.XSHG', '600298.XSHG',
        '600307.XSHG', '600312.XSHG', '600315.XSHG', '600316.XSHG',
        '600325.XSHG', '600329.XSHG', '600335.XSHG', '600338.XSHG',
        '600339.XSHG', '600348.XSHG', '600350.XSHG', '600373.XSHG',
        '600376.XSHG', '600380.XSHG', '600388.XSHG', '600392.XSHG',
        '600409.XSHG', '600410.XSHG', '600415.XSHG', '600418.XSHG',
        '600426.XSHG', '600428.XSHG', '600435.XSHG', '600446.XSHG',
        '600460.XSHG', '600466.XSHG', '600478.XSHG', '600486.XSHG',
        '600497.XSHG', '600500.XSHG', '600507.XSHG', '600511.XSHG',
        '600515.XSHG', '600521.XSHG', '600528.XSHG', '600529.XSHG',
        '600535.XSHG', '600545.XSHG', '600549.XSHG', '600557.XSHG',
        '600563.XSHG', '600565.XSHG', '600566.XSHG', '600567.XSHG',
        '600572.XSHG', '600575.XSHG', '600580.XSHG', '600582.XSHG',
        '600597.XSHG', '600598.XSHG', '600623.XSHG', '600633.XSHG',
        '600639.XSHG', '600640.XSHG', '600642.XSHG', '600643.XSHG',
        '600645.XSHG', '600648.XSHG', '600649.XSHG', '600657.XSHG',
        '600664.XSHG', '600667.XSHG', '600673.XSHG', '600675.XSHG',
        '600694.XSHG', '600699.XSHG', '600704.XSHG', '600707.XSHG',
        '600717.XSHG', '600718.XSHG', '600728.XSHG', '600729.XSHG',
        '600733.XSHG', '600737.XSHG', '600739.XSHG', '600748.XSHG',
        '600751.XSHG', '600754.XSHG', '600755.XSHG', '600757.XSHG',
        '600765.XSHG', '600770.XSHG', '600776.XSHG', '600777.XSHG',
        '600779.XSHG', '600782.XSHG', '600787.XSHG', '600801.XSHG',
        '600804.XSHG', '600808.XSHG', '600811.XSHG', '600820.XSHG',
        '600823.XSHG', '600827.XSHG', '600835.XSHG', '600839.XSHG',
        '600845.XSHG', '600859.XSHG', '600862.XSHG', '600863.XSHG',
        '600869.XSHG', '600874.XSHG', '600875.XSHG', '600879.XSHG',
        '600881.XSHG', '600884.XSHG', '600885.XSHG', '600895.XSHG',
        '600901.XSHG', '600903.XSHG', '600908.XSHG', '600909.XSHG',
        '600917.XSHG', '600959.XSHG', '600967.XSHG', '600970.XSHG',
        '600985.XSHG', '600996.XSHG', '601000.XSHG', '601003.XSHG',
        '601005.XSHG', '601016.XSHG', '601019.XSHG', '601068.XSHG',
        '601098.XSHG', '601099.XSHG', '601106.XSHG', '601118.XSHG',
        '601127.XSHG', '601128.XSHG', '601139.XSHG', '601168.XSHG',
        '601179.XSHG', '601200.XSHG', '601228.XSHG', '601233.XSHG',
        '601333.XSHG', '601608.XSHG', '601611.XSHG', '601678.XSHG',
        '601689.XSHG', '601699.XSHG', '601717.XSHG', '601718.XSHG',
        '601799.XSHG', '601801.XSHG', '601811.XSHG', '601866.XSHG',
        '601869.XSHG', '601880.XSHG', '601928.XSHG', '601958.XSHG',
        '601966.XSHG', '601969.XSHG', '603000.XSHG', '603025.XSHG',
        '603056.XSHG', '603077.XSHG', '603198.XSHG', '603225.XSHG',
        '603228.XSHG', '603233.XSHG', '603328.XSHG', '603338.XSHG',
        '603355.XSHG', '603377.XSHG', '603444.XSHG', '603486.XSHG',
        '603515.XSHG', '603517.XSHG', '603556.XSHG', '603568.XSHG',
        '603605.XSHG', '603650.XSHG', '603659.XSHG', '603707.XSHG',
        '603708.XSHG', '603712.XSHG', '603766.XSHG', '603806.XSHG',
        '603816.XSHG', '603858.XSHG', '603866.XSHG', '603868.XSHG',
        '603882.XSHG', '603883.XSHG', '603885.XSHG', '603888.XSHG',
        '603939.XSHG'
    ]

    def __init__(self, start: datetime, end: datetime, limit_size=-1):
        self.index = 0
        self.start = start
        self.end = end
        from earnmi.data.MarketImpl import MarketImpl
        self.market = MarketImpl()
        self.market.setToday(end + timedelta(days=1))
        self.limitSize = len(ZZ500DataSource.SZ500_JQ_CODE_LIST)
        if limit_size > 0:
            self.limitSize = min(limit_size, self.limitSize)

    """
    清空缓存
    """

    def clearAll(self):
        code_list = ZZ500DataSource.SZ500_JQ_CODE_LIST
        for code in code_list:
            self.market.addNotice(code)
            bars = self.market.getHistory().clean(code)
            self.market.removeNotice(code)
            return code, bars

    def nextBars(self) -> Tuple[Sequence['BarData'], str]:
        # if self.index > 2:
        #     return None,None
        code_list = ZZ500DataSource.SZ500_JQ_CODE_LIST
        if self.index < self.limitSize:
            code = code_list[self.index]
            self.index += 1
            self.market.addNotice(code)
            bars = self.market.getHistory().getKbarFrom(code, self.start)
            self.market.removeNotice(code)
            return bars, code
        return None, None