Read a file for symbols that are in your own private file to only process your own symbols.

td753764td753764 Posts: 67
edited January 2019 in How To

Hi All,

I was recently asked a question on how does someone read a file with a private list of symbols.

Step 1. Create your own file in the User Data tab.

I created a file that has my list of symbols. The file is called "secret_symbol_list.txt"

Each row of the file has a different symbol. Here is my "secret_symbol_list.txt"

IBM
ORCL
MSFT
SPY
FB
M
XOM

For those unfamiliar with the CloudQuant User Data Tab, this is what it looks like:

Step 2. Read the file in on_strategy_start

Not every algo has an on_strategy_start() method. I use this method to load up the symbols into a class list variable so that it is available to all instances as my algo runs.

    @classmethod
    def on_strategy_start(cls, md, service, account):
        # read the user data file as a string
        cls.symbol_list = []
        symbols = service.read_file('secret_symbol_list.txt', format='raw')

        # create a symbol list by splitting the lines into a list of symbols
        cls.symbol_list = symbols.splitlines()

Step 3. Return True in is_symbol_qualified if the symbol is in your list

The is_symbol_qualified method lets the backtest simulation engine know if we are using this symbol for trading.

    @classmethod
    def is_symbol_qualified(cls, symbol, md, service, account):
    # qualify only symbol in both the symbol list and in the entry stats file
        if symbol in cls.symbol_list:
            print("This symbol {} is in my list.".format(symbol))
            return True

Full Working Script that uses this technique

from cloudquant.interfaces import Strategy
import talib
import numpy

#####################################################
# Simple Exponential Moving Average Script
# When yesterday's EMA is above the previous day's EMA
# then go long - else go short


class Simple_EMA(Strategy):

    @classmethod
    def on_strategy_start(cls, md, service, account):
        # read the user data file as a string
        cls.symbol_list = []
        symbols = service.read_file('secret_symbol_list.txt', format='raw')

        # create a symbol list by splitting the lines into a list of symbols
        cls.symbol_list = symbols.splitlines()

    @classmethod
    def is_symbol_qualified(cls, symbol, md, service, account):
    # qualify only symbol in both the symbol list and in the entry stats file
        if symbol in cls.symbol_list:
            print("This symbol {} is in my list.".format(symbol))
            return True


    def on_start(self, md, order, service, account): #    
        myBars = md.bar.daily(start=-21) # grab 21 bars, EMA uses 20, we want yesterdays and the day before so grab 21
        close = myBars.close # pull out just the close prices
        EMA = talib.MA(close,timeperiod=20,matype=1) # TALIB Moving Average matype=1 = Exponential Moving Average
        EMAlist = numpy.ndarray.tolist(EMA) # TALIB returns a numpy array, lets turn that back into a basic list
        #print self.symbol,EMAlist
        if EMAlist[-1] > EMAlist[-2] : # if yesterday's EMA is above the previous day go long
            order.send(self.symbol, 'buy', 100, type='MKT')  # Market order, no price required
            print("long entry ordered on {}".format(self.symbol))
        if EMAlist[-1] < EMAlist[-2] : # if yesterday's EMA is below the previous day go short
            order.send(self.symbol, 'sell', 100, type='MKT')  # Market order, no price required
            print("short entry ordered on {}".format(self.symbol))

    def on_minute_bar(self, event, md, order, service, account, bar):
        if event.timestamp > service.time(15,44): # at the end of the day, exit the position and terminate the script
            if account[self.symbol].position.shares > 0:
                order.send(self.symbol, 'sell', 100, type='MKT')  # Market order, no price required
                print("sell to cover ordered on {}".format(self.symbol))
            elif account[self.symbol].position.shares < 0:
                order.send(self.symbol, 'buy', 100, type='MKT')  # Market order, no price required
                print("buy to cover ordered on {}".format(self.symbol))

Comments

  • Also would be great to see a good example of working with files which contain list of trades. For example
    AAPL,20180101 12:15:18.200,200,"buy","mkt"
    AAPL,20180101 12:20:21.300,200,"sell","mkt"
    AAPL,20180101 15:30:00.000,500,"buy","MOC"

  • Hi:

    If you are using a CSV file, it is easier to have column headings.

    For this example, I am going to use a file called signals.csv which contains the following data.

    Symbol,Timestamp,Qty,Side,Order_Type,Price
    AAPL,20180710 12:15:18.200,200,buy,MKT,0
    AAPL,20180710 12:20:21.300,200,sell,MKT,0
    AAPL,20180710 15:25:00.000,500,buy,MOC,0
    MSFT,20180710 09:45:18.200,200,buy,MKT,0
    MSFT,20180710 10:05:48.200,200,buy,MKT,0
    

    Reading in the data from my signals.csv file can be accomplished using the following line of code. The return of this will be a list containing dictionary data.

    data = service.read_file('signals.csv', 'csv')

    To See what is in data you can print it out by iterating through the list.

    for signal in data:
        print(signal)
    

    This produces the following prints:

    {'Order_Type': 'MKT', 'Timestamp': '20180710 12:15:18.200', 'Price': 0, 'Side': 'buy', 'Qty': 200, 'Symbol': 'AAPL'}
    {'Order_Type': 'MKT', 'Timestamp': '20180710 12:20:21.300', 'Price': 0, 'Side': 'sell', 'Qty': 200, 'Symbol': 'AAPL'}
    {'Order_Type': 'MOC', 'Timestamp': '20180710 15:25:00.000', 'Price': 0, 'Side': 'buy', 'Qty': 500, 'Symbol': 'AAPL'}
    {'Order_Type': 'MKT', 'Timestamp': '20180710 09:45:18.200', 'Price': 0, 'Side': 'buy', 'Qty': 200, 'Symbol': 'MSFT'}
    {'Order_Type': 'MKT', 'Timestamp': '20180710 10:05:48.200', 'Price': 0, 'Side': 'buy', 'Qty': 200, 'Symbol': 'MSFT'}
    

    Because this is a list of dictionaries you can now reference each of the elements by name. For example:

    for signal in data:
        print(signal['Timestamp'])
    

    Timestamps, datetime, MUTS - dealing with problems of converting your timestamp.

    My data file has a representation of the timestamp that looks like: 20180710 12:15:18.200

    To process this we may need to convert the timestamp string into a datetime field. code that I used for that process. The following code handles this logic for me.

        for signal in data:
            # print the signal
            print("signal #{} ={}".format(signal_count, signal))
            datetime_object = datetime.strptime(signal['Timestamp'], '%Y%m%d %H:%M:%S.%f')
            signal_count +=1
            # if our date matches, then add the signal to the today's signal list
            if datetime_object.date() == d.date():
                cls.today_signals.append(signal)
    

    Full Working Script - To Replay a Signal file.

    from cloudquant.interfaces import Strategy
    import talib
    import numpy
    from datetime import datetime
    import pytz
    
    #####################################################
    # Replay a CSV File of Timestamped orders.
    # This algo requires a file called signals.csv 
    # The file must have columns for:
    # Symbol,Timestamp,Qty,Side,Order_Type,Price
    #
    # Timestamp in NY Time. Format example: 20180711 09:45:04.200
    # Side = "buy" or "sell"
    # Order_Type = "MKT", "LMT"
    # Quantity should be positive.
    
    class ReadCSV(Strategy):
    
        @classmethod
        def on_strategy_start(cls, md, service, account):
            # read the signal data file, which is in a CSV file with column labels.
            data = service.read_file('signals.csv', 'csv')
    
            # print the data
            print("Signal Data:\n\n")
            for signal in data:
                print(signal)
    
            # Create a class variable to contain the signals just for the today's specific signals    
            cls.today_signals = []
    
            # Get the simulation day's timestamp. We use this to only process data
            # for the given simulation day's signals. Ignore signals from the input
            # signals that don't have the same day.
            now = service.system_time
            d = datetime.fromtimestamp(now/1000000) #.strftime('%Y-%m-%d %H:%M:%S')+'.%06d'%(now%1000000)
    
            # create a variable to track number of signals
            signal_count = 1
    
            # for each signal dictionary in data
            for signal in data:
                # print the signal
                print("signal #{} ={}".format(signal_count, signal))
                datetime_object = datetime.strptime(signal['Timestamp'], '%Y%m%d %H:%M:%S.%f')
                signal_count +=1
                # if our date matches, then add the signal to the today's signal list
                if datetime_object.date() == d.date():
                    cls.today_signals.append(signal)
    
        @classmethod
        def is_symbol_qualified(cls, symbol, md, service, account):
            #return symbol in ['FB', 'AAPL', 'NFLX', 'GOOG', 'SPY', 'AMZN', 'MSFT']
            return True
    
    
        # called every minute before the first on_trade of every new minute, or 5 seconds after a new minute starts
        def on_minute_bar(self, event, md, order, service, account, bar):
            now = service.system_time
            nowDt = datetime.fromtimestamp(now/1000000)
            for signal in self.today_signals:
                if signal['Symbol'] == self.symbol:
                    fileDt = datetime.strptime(signal['Timestamp'], '%Y%m%d %H:%M:%S.%f')
                    # The imput timestamps are in timezone NY (EST) 
                    fileDt = pytz.timezone('America/New_York').localize(fileDt)
                    dt_UTC = fileDt.astimezone(pytz.timezone('UTC')) #Get the UTC timestamp, because the simulator runs on UTC Time
                    #print(dt_UTC, signal['Timestamp'], fileDt)
                    if nowDt.time().hour == dt_UTC.time().hour:
                        if nowDt.time().minute == dt_UTC.time().minute:
                            Side = signal["Side"]
                            Order_Type = signal["Order_Type"]
                            Price = signal["Price"]
                            Qty = signal["Qty"]
                            order.send(self.symbol, Side, Qty, type=Order_Type, price=Price)
    
Sign In or Register to comment.