Пример #1
0
    def analyseRule(self):
        """
        ?
        """

        Logger.log(logging.INFO, "Analysing Rule", {"scope":__name__, "Rule":self._ruleTableName})

        equityCount = self._getEquityCount()
        potentialRuleMatches = self._getPotentialRuleMatches()

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        cursor = connection.cursor()

        try:
            query = "select count(1) from '%s' where Match = 1;" % self._ruleTableName
            cursor.execute(query)
            actualRuleMatches = int(cursor.fetchone()[0])

            query = "delete from Rules where Rule = '%s'" % self._ruleTableName
            cursor.execute(query)

            # Unit Testing is easier if the value is stored...
            self._matchesPerDay = actualRuleMatches / potentialRuleMatches * equityCount
            query = "insert into Rules values('%s',%s)" % (self._ruleTableName, self._matchesPerDay)
            cursor.execute(query)

        except sqlite3.OperationalError:
            Logger.log(logging.INFO, "Error Analysing Rule", {"scope":__name__, "Rule":self._ruleTableName})

        connection.commit()

        connection.close()
Пример #2
0
    def updateIndicator(self):
        """
        Calculate and Store the (New) Indicator Data.
        """

        start = self._getLatestDate()

        Logger.log(
            logging.INFO, "Updating Indicator", {
                "scope": __name__,
                "indicator": self._tableName,
                "code": self._tickerCode,
                "start": str(start)
            })

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        newRecords = self._indicatorDataFrame.query("Date > '%s'" %
                                                    (str(start)))

        connection.executemany(self._insertQuery,
                               newRecords.to_records(index=True))

        connection.commit()

        connection.close()
Пример #3
0
    def evaluateRule(self):
        """
        ?.
        """

        start = self._getLatestDate()

        Logger.log(logging.INFO, "Evaluating Rule", {
            "scope": __name__,
            "Rule": self._ruleTableName,
            "start": str(start)
        })

        self._restrictedSelectQuery = "%s where Date > '%s'" % (
            self._selectQuery, start)

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        self._ruleData = read_sql_query(self._restrictedSelectQuery,
                                        connection, 'Date')

        self._ruleData['Match'] = self._ruleData['Match'].astype(float)

        connection.executemany(self._insertQuery,
                               self._ruleData.to_records(index=True))
        connection.commit()

        connection.close()
Пример #4
0
    def askHorse(self, latestDate):

        self.tradeDetails = []

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        query = ("select r1.Code, r1.Date "
            "from '%s' r1 "
            " inner join '%s' r2 on r2.Match = 1 and r1.Date = r2.Date and r1.Code = r2.Code "
            " inner join '%s' r3 on r3.Match = 1 and r1.Date = r3.Date and r1.Code = r3.Code "
            "where r1.Match = 1 and r1.Date = '%s'") % (self._rule1, self._rule2, self._rule3, latestDate)

        trades = None

        cursor = connection.cursor()
        try:
            cursor.execute(query)
            # print(query)
            trades = cursor.fetchall()
        except sqlite3.OperationalError:
            Logger.log(logging.INFO, "Error Getting Trades", {"scope":__name__})

        connection.close()

        for trade in trades:
            tradeSummary = ("%s %s using %s") % (self._type, trade[0], self._exit)
            strategyDetail = ("Strategy: Mean: %s, Median: %s, Total: %s, Trades: %s, Sharpe Ratio: %s, Drawdown: %s") % (str(self.meanResultPerTrade), str(self.medianResultPerTrade), str(self.totalProfit), str(self.numberOfTrades), str(self.sharpeRatio), str(self.maximumDrawdown))
            rulesDetail = ("Rules: '%s', '%s' and '%s'") % (self._rule1, self._rule2, self._rule3)

            tradeDetail = "%s (%s)\n%s" % (tradeSummary, strategyDetail, rulesDetail)
            self.tradeDetails.append(tradeDetail)
            Logger.log(logging.INFO, "Suggested Trade", {"scope":__name__, "tradeDetail":tradeDetail})

        return len(self.tradeDetails) > 0
Пример #5
0
    def importData(self):
        """
        Import (New) Data from Yahoo.
        """

        start = self._getLatestDate()
        end = self._getTodaysDate()

        Logger.log(logging.INFO, "Loading Data", {"scope":__name__, "tickerCode":self._tickerCode, "start":str(start), "end":str(end)})
        self._data = DataReader(self._tickerCode, "yahoo", start, end)

        self._data['Code'] = self._tickerCode

        for item in ['Open', 'High', 'Low']:
            self._data[item] = self._data[item] * self._data['Adj Close'] / self._data['Close']

        self._data.drop('Close', axis=1, inplace=True)
        self._data.rename(columns={'Adj Close':'Close'}, inplace=True)
        self._data['Volume'] = self._data['Volume'].astype(float)

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        query = "insert or replace into Equities (Date, Open, High, Low, Volume, Close, Code) values (?,?,?,?,?,?,?)"
        connection.executemany(query, self._data.to_records(index=True))
        connection.commit()

        connection.close()
Пример #6
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestStrategy.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        copyFile(pyswing.database.pySwingTestDatabase,
                 pyswing.database.pySwingDatabase)

        twoRuleStrategy = Strategy(
            "Rule Equities Indicator_BB20 abs(t1.Close - t2.upperband) < abs(t1.Close - t2.middleband)",
            "Rule Equities abs(Close - High) * 2 < abs(Close - Low)",
            "Exit TrailingStop3.0 RiskRatio2", "Buy")
        twoRuleStrategy.evaluateTwoRuleStrategy()

        threeRuleStrategy = Strategy(
            "Rule Equities Indicator_BB20 abs(t1.Close - t2.upperband) < abs(t1.Close - t2.middleband)",
            "Rule Equities abs(Close - High) * 2 < abs(Close - Low)",
            "Exit TrailingStop3.0 RiskRatio2", "Buy",
            "Rule Indicator_RSI RSI > 20")
        threeRuleStrategy.evaluateThreeRuleStrategy()

        historicTrades = Strategy(
            "Rule Equities Indicator_BB20 abs(t1.Close - t2.upperband) < abs(t1.Close - t2.middleband)",
            "Rule Equities abs(Close - High) * 2 < abs(Close - Low)",
            "Exit TrailingStop3.0 RiskRatio2", "Buy",
            "Rule Indicator_RSI RSI > 20")
        historicTrades.generateHistoricTrades()
Пример #7
0
def getActiveStrategies():

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "select rule1, rule2, exit, type, rule3, meanResultPerTrade, medianResultPerTrade, totalProfit, numberOfTrades, sharpeRatio, maximumDrawdown from ActiveStrategy where active = 1"

    strategies = None

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        strategies = cursor.fetchall()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Getting Strategies",
                   {"scope": __name__})

    connection.close()

    strategiesList = []
    for strategyRow in strategies:

        strategy = Strategy(strategyRow[0], strategyRow[1], strategyRow[2],
                            strategyRow[3], strategyRow[4])
        strategiesList.append(strategy)

        strategy.meanResultPerTrade = strategyRow[5]
        strategy.medianResultPerTrade = strategyRow[6]
        strategy.totalProfit = strategyRow[7]
        strategy.numberOfTrades = strategyRow[8]
        strategy.sharpeRatio = strategyRow[9]
        strategy.maximumDrawdown = strategyRow[10]

    return strategiesList
Пример #8
0
    def setUpClass(self):

        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestMarketRule.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2014, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())

        pretendDate = datetime.datetime(2015, 9, 1)
        with patch.object(Equity, '_getTodaysDate', return_value=pretendDate) as mock_method:

            self._equity = Equity("WOR.AX")
            self._equity.importData()

        indicatorADI = IndicatorADI()
        indicatorADI.updateIndicator()

        self.rule = MarketRule("Indicator_ADI", "ADI > 0")
        self.rule.evaluateRule()
Пример #9
0
def getStrategies(numberOfTrades, returnPerTrade):

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "select rule1, rule2, rule3, exit, type from ThreeRuleStrategy where numberOfTrades > %s and resultPerTrade > %s" % (
        numberOfTrades, returnPerTrade)

    strategies = None

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        strategies = cursor.fetchall()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Getting Strategies",
                   {"scope": __name__})

    connection.close()

    strategiesList = []
    for strategyRow in strategies:
        strategy = Strategy(strategyRow[0], strategyRow[1], strategyRow[3],
                            strategyRow[4], strategyRow[2])
        strategiesList.append(strategy)

    return strategiesList
Пример #10
0
    def _getLatestDate(self):

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        query = "select max(Date) from %s" % (self._tableName)

        cursor = connection.cursor()

        dateString = None
        try:
            cursor.execute(query)
            dateString = cursor.fetchone()[0]
        except sqlite3.OperationalError:
            Logger.log(logging.INFO, "Table Does Not Exist", {
                "scope": __name__,
                "table": self._tableName
            })

        connection.close()

        date = pyswing.constants.pySwingStartDate
        if dateString:
            date = datetime.datetime.strptime(dateString, "%Y-%m-%d %H:%M:%S")

        return date
Пример #11
0
def sendEmail(tradeDetails):

    message = "Hello!\n\n"
    for trade in tradeDetails:
        message += trade
        message += "\n\n"

    message += "x"

    subject = None
    if len(tradeDetails) > 0:
        subject = "Horse Says Trade!"
    else:
        subject = "Horse Says Go Back To Bed!"

    header  = 'From: %s\n' % "*****@*****.**"
    header += 'To: %s\n' % ','.join(["*****@*****.**"])
    header += 'Subject: %s\n\n' % subject
    message = header + message

    server = smtplib.SMTP("smtp.gmail.com:587")
    server.starttls()
    server.login("*****@*****.**", "abcABC1234567890")
    problems = server.sendmail("*****@*****.**", ["*****@*****.**"], message)
    server.quit()

    if problems:
        Logger.log(logging.ERROR, "Error Sending E-mail", {"scope": __name__, "problems": str(problems)})
Пример #12
0
def getActiveStrategies():

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "select rule1, rule2, exit, type, rule3, meanResultPerTrade, medianResultPerTrade, totalProfit, numberOfTrades, sharpeRatio, maximumDrawdown from ActiveStrategy where active = 1"

    strategies = None

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        strategies = cursor.fetchall()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Getting Strategies", {"scope":__name__})

    connection.close()

    strategiesList = []
    for strategyRow in strategies:

        strategy = Strategy(strategyRow[0], strategyRow[1], strategyRow[2], strategyRow[3], strategyRow[4])
        strategiesList.append(strategy)

        strategy.meanResultPerTrade = strategyRow[5]
        strategy.medianResultPerTrade = strategyRow[6]
        strategy.totalProfit = strategyRow[7]
        strategy.numberOfTrades = strategyRow[8]
        strategy.sharpeRatio = strategyRow[9]
        strategy.maximumDrawdown = strategyRow[10]

    return strategiesList
Пример #13
0
    def setUpClass(self):

        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestMarketRule.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2014, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())

        pretendDate = datetime.datetime(2015, 9, 1)
        with patch.object(Equity, '_getTodaysDate',
                          return_value=pretendDate) as mock_method:

            self._equity = Equity("WOR.AX")
            self._equity.importData()

        indicatorADI = IndicatorADI()
        indicatorADI.updateIndicator()

        self.rule = MarketRule("Indicator_ADI", "ADI > 0")
        self.rule.evaluateRule()
Пример #14
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestDatabase.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)
        deleteFile(pyswing.database.pySwingTestDatabase)

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())

        pretendDate = datetime.datetime(2015, 7, 1)
        with patch.object(Equity, '_getTodaysDate',
                          return_value=pretendDate) as mock_method:
            args = "-n unitTest".split()
            importData(args)

        args = "-n unitTest".split()
        updateIndicators(args)

        args = "-n unitTest".split()
        evaluateRules(args)

        args = "-n unitTest".split()
        analyseRules(args)

        args = "-n unitTest".split()
        calculateExitValues(args)
Пример #15
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestDatabase.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)
        deleteFile(pyswing.database.pySwingTestDatabase)

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())

        pretendDate = datetime.datetime(2015, 7, 1)
        with patch.object(Equity, '_getTodaysDate', return_value=pretendDate) as mock_method:
            args = "-n unitTest".split()
            importData(args)

        args = "-n unitTest".split()
        updateIndicators(args)

        args = "-n unitTest".split()
        evaluateRules(args)

        args = "-n unitTest".split()
        analyseRules(args)

        args = "-n unitTest".split()
        calculateExitValues(args)
Пример #16
0
    def test_lotsOfLoggers(self):

        aLogger = Logger._getLogger()
        anotherLogger = Logger._getLogger()

        self.assertIsNotNone(aLogger, "Check A Logger")
        self.assertIsNotNone(anotherLogger, "Check Another Logger")
        self.assertEqual(len(anotherLogger.handlers), 1, "Check Handlers")
Пример #17
0
    def test_lotsOfLoggers(self):

        aLogger = Logger._getLogger()
        anotherLogger = Logger._getLogger()

        self.assertIsNotNone(aLogger, "Check A Logger")
        self.assertIsNotNone(anotherLogger, "Check Another Logger")
        self.assertEqual(len(anotherLogger.handlers), 1, "Check Handlers")
Пример #18
0
    def __init__(self):
        """
        ?
        """

        Logger.log(logging.DEBUG, "Log Object Creation", {"scope": __name__})

        self._rules = self._getRules()
Пример #19
0
    def __init__(self):
        """
        ?
        """

        Logger.log(logging.DEBUG, "Log Object Creation", {"scope": __name__})

        self._rules = self._getRules()
Пример #20
0
def createDatabase(argv):
    """
    Create Database.

    :param argv: Command Line Parameters.

    -n = Name

    Example:

    python -m pyswing.CreateDatabase -n asx
    """

    Logger.log(logging.INFO, "Log Script Call", {"scope":__name__, "arguments":" ".join(argv)})
    Logger.pushLogData("script", __name__)

    marketName = ""

    try:
        shortOptions = "n:dh"
        longOptions = ["marketName=", "debug", "help"]
        opts, __ = getopt.getopt(argv, shortOptions, longOptions)
    except getopt.GetoptError as e:
        Logger.log(logging.ERROR, "Error Reading Options", {"scope": __name__, "exception": str(e)})
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-d", "--debug"):
            Logger().setLevel(logging.DEBUG)
        elif opt in ("-h", "--help"):
            print("?")
            usage()
            sys.exit()
        elif opt in ("-n", "--marketName"):
            marketName = arg

    if marketName != "":

        pyswing.database.initialiseDatabase(marketName)
        databaseFilePath = pyswing.database.pySwingDatabase
        scriptFilePath = pyswing.constants.pySwingDatabaseScript

        Logger.log(logging.INFO, "Creating Database", {"scope":__name__, "databaseFilePath":databaseFilePath, "scriptFilePath":scriptFilePath})

        query = open(pyswing.constants.pySwingDatabaseScript, 'r').read()
        connection = sqlite3.connect(databaseFilePath)
        c = connection.cursor()
        c.executescript(query)
        connection.commit()
        c.close()
        connection.close()
        TeamCity.setBuildResultText("Created Database")

    else:
        Logger.log(logging.ERROR, "Missing Options", {"scope": __name__, "options": str(argv)})
        usage()
        sys.exit(2)
Пример #21
0
    def evaluateRule(self, tickerCode):
        """
        ?

        :param tickerCode:
        """

        self._tickerCode = tickerCode

        start = self._getLatestDate()

        Logger.log(
            logging.INFO, "Evaluating Rule", {
                "scope": __name__,
                "Rule": self._ruleTableName,
                "code": self._tickerCode,
                "start": str(start)
            })

        self._restrictedSelectQuery = "%s where r.Code = '%s' and r.Date >= '%s'" % (
            self._selectQuery, self._tickerCode, start)

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        self._ruleData = read_sql_query(self._restrictedSelectQuery,
                                        connection, 'Date')

        self._ruleData['LastCrosser'] = self._ruleData['Crosser'].shift(1)
        self._ruleData['LastCrossee'] = self._ruleData['Crossee'].shift(1)

        try:
            self._ruleData['Match'] = (
                self._ruleData['Crosser'] > self._ruleData['Crossee']
            ) & (self._ruleData['LastCrossee'] > self._ruleData['LastCrosser'])
            self._ruleData['Match'] = self._ruleData['Match'].astype(float)
        except TypeError as e:
            # NOTE:  Throws "TypeError: unorderable types: float() > NoneType()" if there is no data (e.g. SMA_200 for datasets smaller than 200)
            Logger.log(
                logging.ERROR, "Error Evaluating Rule", {
                    "scope": __name__,
                    "Rule": self._ruleTableName,
                    "exception": str(e)
                })
            self._ruleData['Match'] = 0.0
            self._ruleData['Match'] = self._ruleData['Match'].astype(float)

        self._ruleData.drop('Crosser', axis=1, inplace=True)
        self._ruleData.drop('Crossee', axis=1, inplace=True)
        self._ruleData.drop('LastCrosser', axis=1, inplace=True)
        self._ruleData.drop('LastCrossee', axis=1, inplace=True)

        newRecords = self._ruleData.query("Date > '%s'" % (str(start)))

        connection.executemany(self._insertQuery,
                               newRecords.to_records(index=True))
        connection.commit()

        connection.close()
Пример #22
0
    def setUpClass(self):

        Logger.pushLogData("unitTesting", __name__)

        forceWorkingDirectory()

        pyswing.database.pySwingDatabase = None
        pyswing.database.pySwingDatabaseInitialised = False
        pyswing.database.pySwingDatabaseOverridden = False
Пример #23
0
def importData(argv):
    """
    Import Share Data.

    :param argv: Command Line Parameters.

    -n = Name

    Example:

    python -m pyswing.ImportData -n asx
    """

    Logger.log(logging.INFO, "Log Script Call", {"scope":__name__, "arguments":" ".join(argv)})
    Logger.pushLogData("script", __name__)

    marketName = ""

    try:
        shortOptions = "n:dh"
        longOptions = ["marketName=", "debug", "help"]
        opts, __ = getopt.getopt(argv, shortOptions, longOptions)
    except getopt.GetoptError as e:
        Logger.log(logging.ERROR, "Error Reading Options", {"scope": __name__, "exception": str(e)})
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-d", "--debug"):
            Logger().setLevel(logging.DEBUG)
        elif opt in ("-h", "--help"):
            print("?")
            usage()
            sys.exit()
        elif opt in ("-n", "--marketName"):
            marketName = arg

    if marketName != "":

        pyswing.database.initialiseDatabase(marketName)

        Logger.log(logging.INFO, "Import Market Data", {"scope":__name__, "market":marketName})

        tickerCodesRelativeFilePath = "resources/%s.txt" % (marketName)

        market = Market(tickerCodesRelativeFilePath)

        for index, row in market.tickers.iterrows():
            equity = Equity(row[0])
            equity.importData()

        TeamCity.setBuildResultText("Imported Data from Yahoo")

    else:
        Logger.log(logging.ERROR, "Missing Options", {"scope": __name__, "options": str(argv)})
        usage()
        sys.exit(2)
def generateHistoricTradesForActiveStrategies(argv):
    """
    Generate (in the HistoricTrades database table) Historic Trades for the Active Strategies.

    Empty the database table and then fill it with the historic trades for all the active strategies.

    :param argv: Command Line Parameters.

    -n = Name

    Example:

    python -m pyswing.GenerateHistoricTradesForActiveStrategies -n asx
    """

    Logger.log(logging.INFO, "Log Script Call", {"scope":__name__, "arguments":" ".join(argv)})
    Logger.pushLogData("script", __name__)

    marketName = ""

    try:
        shortOptions = "n:dh"
        longOptions = ["marketName=", "debug", "help"]
        opts, __ = getopt.getopt(argv, shortOptions, longOptions)
    except getopt.GetoptError as e:
        Logger.log(logging.ERROR, "Error Reading Options", {"scope": __name__, "exception": str(e)})
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-d", "--debug"):
            Logger().setLevel(logging.DEBUG)
        elif opt in ("-h", "--help"):
            print("?")
            usage()
            sys.exit()
        elif opt in ("-n", "--marketName"):
            marketName = arg

    if marketName != "":

        pyswing.database.initialiseDatabase(marketName)

        Logger.log(logging.INFO, "Generate Historic Trades for Active Strategies", {"scope":__name__, "market":marketName})

        emptyHistoricTradesTable()

        strategies = getActiveStrategies()

        for strategy in strategies:
            strategy.generateHistoricTrades()

    else:
        Logger.log(logging.ERROR, "Missing Options", {"scope": __name__, "options": str(argv)})
        usage()
        sys.exit(2)
Пример #25
0
    def calculateExitValues(self):

        Logger.log(logging.INFO, "Calculating Exit Values", {
            "scope": __name__,
            "Rule": self._tableName,
            "code": self._tickerCode
        })

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        self._selectBuyQuery = "select e.Date as Date, e.Date as TradeDate, e.Code, e.Open, e.Close, e.High, e.Low, x.Type, x.ExitValue, x.NumberOfDays, x.ExitDetail from Equities e left join '%s' x on e.Date = x.MatchDate and e.Code = x.Code and x.Type = 'Buy' where e.Code = '%s' and x.ExitValue is NULL" % (
            self._tableName, self._tickerCode)
        self._buyExitValueDataFrame = read_sql_query(self._selectBuyQuery,
                                                     connection, "Date")

        numberOfRows = self._buyExitValueDataFrame.shape[0]
        for i in range(0, numberOfRows):
            self.calculateExitValueForBuy(i, numberOfRows - i)

        self._buyExitValueDataFrame.drop('Open', axis=1, inplace=True)
        self._buyExitValueDataFrame.drop('Close', axis=1, inplace=True)
        self._buyExitValueDataFrame.drop('High', axis=1, inplace=True)
        self._buyExitValueDataFrame.drop('Low', axis=1, inplace=True)
        self._buyExitValueDataFrame['MatchDate'] = self._buyExitValueDataFrame[
            'TradeDate'].shift(1)
        self._buyExitValueDataFrame.drop('TradeDate', axis=1, inplace=True)

        newRecords = self._buyExitValueDataFrame.query("Type=='Buy'")
        connection.executemany(self._insertQuery,
                               newRecords.to_records(index=True))
        connection.commit()

        self._selectSellQuery = "select e.Date as Date, e.Date as TradeDate, e.Code, e.Open, e.Close, e.High, e.Low, x.Type, x.ExitValue, x.NumberOfDays, x.ExitDetail from Equities e left join '%s' x on e.Date = x.MatchDate and e.Code = x.Code and x.Type = 'Sell' where e.Code = '%s' and x.ExitValue is NULL" % (
            self._tableName, self._tickerCode)
        self._sellExitValueDataFrame = read_sql_query(self._selectSellQuery,
                                                      connection, "Date")

        numberOfRows = self._sellExitValueDataFrame.shape[0]
        for i in range(0, numberOfRows):
            self.calculateExitValueForSell(i, numberOfRows - i)

        self._sellExitValueDataFrame.drop('Open', axis=1, inplace=True)
        self._sellExitValueDataFrame.drop('Close', axis=1, inplace=True)
        self._sellExitValueDataFrame.drop('High', axis=1, inplace=True)
        self._sellExitValueDataFrame.drop('Low', axis=1, inplace=True)
        self._sellExitValueDataFrame[
            'MatchDate'] = self._sellExitValueDataFrame['TradeDate'].shift(1)
        self._sellExitValueDataFrame.drop('TradeDate', axis=1, inplace=True)

        newRecords = self._sellExitValueDataFrame.query("Type=='Sell'")
        connection.executemany(self._insertQuery,
                               newRecords.to_records(index=True))
        connection.commit()

        connection.close()
Пример #26
0
    def test_log(self):
        with patch.object(Logger._getLogger(), '_log',
                          return_value=None) as mock_method:

            # Assumes that the default log level is DEBUG

            Logger.log(logging.DEBUG, "Test Debug Log Entry", {
                "key1": "value1",
                "key2": "value2"
            })
            self.assertEqual(1, mock_method.call_count)

            Logger.log(logging.INFO, "Test Info Log Entry", {
                "key1": "value1",
                "key2": "value2"
            })
            self.assertEqual(2, mock_method.call_count)

            Logger.log(logging.WARN, "Test Warning Log Entry", {
                "key1": "value1",
                "key2": "value2"
            })
            self.assertEqual(3, mock_method.call_count)

            Logger.log(logging.ERROR, "Test Error Log Entry", {
                "key1": "value1",
                "key2": "value2"
            })
            self.assertEqual(4, mock_method.call_count)
Пример #27
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.database.overrideDatabase("output/TestCalculateExitValues.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())
Пример #28
0
def analyseRules(argv):
    """
    Analyse Rules.

    :param argv: Command Line Parameters.

    -n = Name

    Example:

    python -m pyswing.AnalyseRules -n asx
    """

    Logger.log(logging.INFO, "Log Script Call", {"scope":__name__, "arguments":" ".join(argv)})
    Logger.pushLogData("script", __name__)

    marketName = ""

    try:
        shortOptions = "n:dh"
        longOptions = ["marketName=", "debug", "help"]
        opts, __ = getopt.getopt(argv, shortOptions, longOptions)
    except getopt.GetoptError as e:
        Logger.log(logging.ERROR, "Error Reading Options", {"scope": __name__, "exception": str(e)})
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-d", "--debug"):
            Logger().setLevel(logging.DEBUG)
        elif opt in ("-h", "--help"):
            print("?")
            usage()
            sys.exit()
        elif opt in ("-n", "--marketName"):
            marketName = arg

    if marketName != "":

        pyswing.database.initialiseDatabase(marketName)

        Logger.log(logging.INFO, "Analyse Rules", {"scope":__name__, "market":marketName})

        rules = getRules()
        for ruleString in rules:
            rule = Rule(ruleString)
            rule.analyseRule()

        TeamCity.setBuildResultText("Analysed Rules")

    else:
        Logger.log(logging.ERROR, "Missing Options", {"scope": __name__, "options": str(argv)})
        usage()
        sys.exit(2)
Пример #29
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.database.overrideDatabase("output/TestUpdateIndicators.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())
Пример #30
0
    def __init__(self, tickerCode):
        """
        Constructor.

        There isn't much to see here. It just makes a note of the Ticker Code.

        :param tickerCode: Ticker Code.
        """

        Logger.log(logging.DEBUG, "Log Object Creation", {"scope":__name__, "arguments":" ".join({tickerCode})})

        self._tickerCode = tickerCode
Пример #31
0
    def __init__(self, relativeFilePath):
        """
        Read the Ticker Codes in the specified file into a data set (pandas.DataFrame).

        :param relativeFilePath: Relative file path (String) for the (file) list of ticker codes.
        """

        Logger.log(logging.DEBUG, "Log Object Creation", {"scope":__name__, "arguments":" ".join({relativeFilePath})})

        self._relativeFilePath = relativeFilePath

        self.tickers = pandas.read_csv(relativeFilePath)
Пример #32
0
    def evaluateRule(self, tickerCode):
        """
        ?

        :param tickerCode:
        """

        self._tickerCode = tickerCode

        start = self._getLatestDate()

        Logger.log(
            logging.INFO, "Evaluating Rule", {
                "scope": __name__,
                "Rule": self._ruleTableName,
                "code": self._tickerCode,
                "start": str(start)
            })

        # We can't use self._getLatestDate() because we need data from before that date...
        self._restrictedSelectQuery = "%s where Code = '%s'" % (
            self._selectQuery, self._tickerCode)

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        self._ruleData = read_sql_query(self._restrictedSelectQuery,
                                        connection, 'Date')

        self._ruleData['Relative'] = self._ruleData[
            self._indicatorColumn].shift(self._relativeIndex * -1)

        if self._comparison == Comparison.GreaterThan:
            self._ruleData['Match'] = self._ruleData[
                self._indicatorColumn] > self._multiplier * self._ruleData[
                    'Relative']
        else:
            self._ruleData['Match'] = self._ruleData[
                self._indicatorColumn] < self._multiplier * self._ruleData[
                    'Relative']

        self._ruleData['Match'] = self._ruleData['Match'].astype(float)

        self._ruleData.drop('Relative', axis=1, inplace=True)
        self._ruleData.drop(self._indicatorColumn, axis=1, inplace=True)

        newRecords = self._ruleData.query("Date > '%s'" % (str(start)))

        connection.executemany(self._insertQuery,
                               newRecords.to_records(index=True))
        connection.commit()

        connection.close()
Пример #33
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestAskHorse.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        copyFile(pyswing.database.pySwingTestDatabase, pyswing.database.pySwingDatabase)
Пример #34
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestAnalyseStrategies.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        copyFile(pyswing.database.pySwingTestDatabase, pyswing.database.pySwingDatabase)
Пример #35
0
def deleteDirectory(relativeDirectoryPath):
    """
    Delete the specified directory.

    :param relativeDirectoryPath: Relative (from the working directory) path to a directory (i.e. that we want to delete).
    """

    try:
        if os.path.exists(relativeDirectoryPath):
            shutil.rmtree(relativeDirectoryPath)
    except OSError as osError:
        Logger.log(logging.ERROR, "Cannot Delete Directory", {"scope":__name__, "directory":relativeDirectoryPath})
        Logger.log(logging.DEBUG, "Caught Exception", {"scope":__name__, "exception":str(osError)})
Пример #36
0
def deleteEmptyThreeRuleStrategies():

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "delete from ThreeRuleStrategy where resultPerTrade is NULL"

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Deleting Empty Three Rule Strategies", {"scope":__name__})

    connection.close()
Пример #37
0
def deleteFile(relativeFilePath):
    """
    Delete the specified file.

    :param relativeFilePath: Relative (from the working directory) path to a file (i.e. that we want to delete).
    """

    try:
        if os.path.exists(relativeFilePath):
            if ("pyswing.db" not in relativeFilePath):
                Logger.log(logging.INFO, "Delete File", {
                    "scope": __name__,
                    "file": relativeFilePath
                })
                os.remove(relativeFilePath)
            else:
                Logger.log(logging.WARN,
                           "Do You Want To Delete This Database?", {
                               "scope": __name__,
                               "file": relativeFilePath
                           })
    except OSError as osError:
        Logger.log(logging.ERROR, "Cannot Delete File", {
            "scope": __name__,
            "directory": relativeFilePath
        })
        Logger.log(logging.DEBUG, "Caught Exception", {
            "scope": __name__,
            "exception": str(osError)
        })
Пример #38
0
def forceWorkingDirectory():
    """
    forceWorkingDirectory() will ensure that the working directory is set to the project root (i.e. /Users/Gary/PycharmProjects/pyswing).

    There is a discrepancy between TeamCity (which always forces the working directory to be the project root) and IDEs
    (e.g. Eclipse, PyCharm) (which, by default, set the working directory to be the directory containing the script being run).
    """

    Logger.log(logging.DEBUG, "Log Method Call", {"scope":__name__, "arguments":""})

    workingDirectory = os.path.abspath(os.path.curdir)
    if (os.path.exists("pyswing") and os.path.exists("test")):
        Logger.log(logging.DEBUG, "Working Directory", {"scope":__name__, "workingDirectory":workingDirectory})
    else:
        newWorkingDirectory = None

        if os.path.exists("../pyswing") and os.path.exists("../test"):
            newWorkingDirectory = os.path.abspath("../")
        elif os.path.exists("../../pyswing") and os.path.exists("../../test"):
            newWorkingDirectory = os.path.abspath("../../")
        elif os.path.exists("../../../pyswing") and os.path.exists("../../../test"):
            newWorkingDirectory = os.path.abspath("../../../")
        elif os.path.exists("../../../../pyswing") and os.path.exists("../../../../test"):
            newWorkingDirectory = os.path.abspath("../../../../")
        elif os.path.exists("../../../../../pyswing") and os.path.exists("../../../../../test"):
            newWorkingDirectory = os.path.abspath("../../../../../")
        elif os.path.exists("../../../../../../pyswing") and os.path.exists("../../../../../../test"):
            newWorkingDirectory = os.path.abspath("../../../../../../")

        if newWorkingDirectory is not None:
            os.chdir(newWorkingDirectory)
            Logger.log(logging.DEBUG, "Changed Working Directory", {"scope":__name__, "old":workingDirectory,"new":newWorkingDirectory})

        else:
            Logger.log(logging.WARN, "Cannot Change Working Directory", {"scope":__name__, "workingDirectory":workingDirectory})
Пример #39
0
def markTwoRuleStrategyAsProcessed(rule1, rule2, type):

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "update TwoRuleStrategy set Searched = 1 where rule1 = '%s' and rule2 = '%s' and type = '%s';" % (rule1, rule2, type)

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Updating Strategy", {"scope":__name__})

    connection.close()
Пример #40
0
def copyFile(relativeSourceFilePath, relativeTargetFilePath):
    """
    Copy the specified file.

    :param relativeSourceFilePath: Relative (from the working directory) path to a file (i.e. source).
    :param relativeTargetFilePath: Relative (from the working directory) path to a file (i.e. target).
    """

    try:
        shutil.copy(relativeSourceFilePath, relativeTargetFilePath)
    except shutil.Error as e:
        Logger.log(
            logging.ERROR, "Cannot Copy File", {
                "scope": __name__,
                "relativeSourceFilePath": relativeSourceFilePath,
                "relativeTargetFilePath": relativeTargetFilePath
            })
        Logger.log(logging.DEBUG, "Caught Exception", {
            "scope": __name__,
            "exception": str(e)
        })
    except IOError as e:
        Logger.log(
            logging.ERROR, "Cannot Copy File", {
                "scope": __name__,
                "relativeSourceFilePath": relativeSourceFilePath,
                "relativeTargetFilePath": relativeTargetFilePath
            })
        Logger.log(logging.DEBUG, "Caught Exception", {
            "scope": __name__,
            "exception": str(e)
        })
Пример #41
0
def emptyHistoricTradesTable():

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "delete from HistoricTrades"

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Deleting Historic Trades", {"scope":__name__})

    connection.close()
Пример #42
0
    def evaluateThreeRuleStrategy(self):
        """
        ?
        """

        Logger.log(logging.INFO, "Evaluating Three-Rule Strategy", {"scope":__name__, "Rule 1":self._rule1, "Rule 2":self._rule2, "Rule 3":self._rule3, "Type":self._type})

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)
        c = connection.cursor()
        sql = self.evaluateThreeRuleSql % (pyswing.globals.pySwingStrategy, self._rule1, self._rule2, self._rule3, self._exit, self._type, self._rule1, self._rule2, self._rule3, self._exit, self._type)
        c.executescript(sql)
        connection.commit()
        c.close()
        connection.close()
Пример #43
0
    def setUpClass(self):
        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.globals.potentialRuleMatches = None
        pyswing.globals.equityCount = None

        pyswing.database.overrideDatabase("output/TestAnalyseRules.db")
        pyswing.constants.pySwingStartDate = datetime.datetime(2015, 1, 1)

        deleteFile(pyswing.database.pySwingDatabase)

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())
Пример #44
0
def deleteEmptyThreeRuleStrategies():

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "delete from ThreeRuleStrategy where resultPerTrade is NULL"

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Deleting Empty Three Rule Strategies",
                   {"scope": __name__})

    connection.close()
Пример #45
0
def emptyHistoricTradesTable():

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "delete from HistoricTrades"

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Deleting Historic Trades",
                   {"scope": __name__})

    connection.close()
Пример #46
0
    def generateHistoricTrades(self):
        """
        ?
        """

        Logger.log(logging.INFO, "Generating Historic Trades", {"scope":__name__, "Rule 1":self._rule1, "Rule 2":self._rule2, "Rule 3":self._rule3, "Type":self._type})

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)
        c = connection.cursor()
        sql = self.insertIntoHistoricTradesSql % (self._type, self._rule1, self._rule2, self._rule3, self._exit, self._type)
        # print(sql)
        c.executescript(sql)
        connection.commit()
        c.close()
        connection.close()
Пример #47
0
    def __init__(self, relativeFilePath):
        """
        Read the Ticker Codes in the specified file into a data set (pandas.DataFrame).

        :param relativeFilePath: Relative file path (String) for the (file) list of ticker codes.
        """

        Logger.log(logging.DEBUG, "Log Object Creation", {
            "scope": __name__,
            "arguments": " ".join({relativeFilePath})
        })

        self._relativeFilePath = relativeFilePath

        self.tickers = pandas.read_csv(relativeFilePath)
Пример #48
0
    def setUpClass(self):

        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.database.overrideDatabase("output/TestRule.db")

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())

        myRule = Rule("Rule - myRule")
        myRule._createTable()

        myOtherRule = Rule("Rule - myOtherRule")
        myOtherRule._createTable()
Пример #49
0
    def setUpClass(self):

        Logger.pushLogData("unitTesting", __name__)
        forceWorkingDirectory()

        pyswing.database.overrideDatabase("output/TestRule.db")

        args = "-n %s" % ("unitTesting")
        createDatabase(args.split())

        myRule = Rule("Rule - myRule")
        myRule._createTable()

        myOtherRule = Rule("Rule - myOtherRule")
        myOtherRule._createTable()
Пример #50
0
def markTwoRuleStrategyAsProcessed(rule1, rule2, type):

    connection = sqlite3.connect(pyswing.database.pySwingDatabase)

    query = "update TwoRuleStrategy set Searched = 1 where rule1 = '%s' and rule2 = '%s' and type = '%s';" % (
        rule1, rule2, type)

    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
    except sqlite3.OperationalError:
        Logger.log(logging.INFO, "Error Updating Strategy",
                   {"scope": __name__})

    connection.close()
Пример #51
0
def overrideDatabase(override):
    """
    Override "pySwingDatabase" (i.e. file path to the SQL Lite database).

    This should only be used for Unit Testing.

    :param override: String (e.g. "output/TestEvaluateRules.db")
    """

    Logger.log(logging.INFO, "Override Database", {"scope": __name__, "override": override})

    global pySwingDatabase
    pySwingDatabase = override

    global pySwingDatabaseOverridden
    pySwingDatabaseOverridden = True
Пример #52
0
    def askHorse(self, latestDate):

        self.tradeDetails = []

        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        query = (
            "select r1.Code, r1.Date "
            "from '%s' r1 "
            " inner join '%s' r2 on r2.Match = 1 and r1.Date = r2.Date and r1.Code = r2.Code "
            " inner join '%s' r3 on r3.Match = 1 and r1.Date = r3.Date and r1.Code = r3.Code "
            "where r1.Match = 1 and r1.Date = '%s'") % (
                self._rule1, self._rule2, self._rule3, latestDate)

        trades = None

        cursor = connection.cursor()
        try:
            cursor.execute(query)
            # print(query)
            trades = cursor.fetchall()
        except sqlite3.OperationalError:
            Logger.log(logging.INFO, "Error Getting Trades",
                       {"scope": __name__})

        connection.close()

        for trade in trades:
            tradeSummary = ("%s %s using %s") % (self._type, trade[0],
                                                 self._exit)
            strategyDetail = (
                "Strategy: Mean: %s, Median: %s, Total: %s, Trades: %s, Sharpe Ratio: %s, Drawdown: %s"
            ) % (str(self.meanResultPerTrade), str(self.medianResultPerTrade),
                 str(self.totalProfit), str(self.numberOfTrades),
                 str(self.sharpeRatio), str(self.maximumDrawdown))
            rulesDetail = ("Rules: '%s', '%s' and '%s'") % (
                self._rule1, self._rule2, self._rule3)

            tradeDetail = "%s (%s)\n%s" % (tradeSummary, strategyDetail,
                                           rulesDetail)
            self.tradeDetails.append(tradeDetail)
            Logger.log(logging.INFO, "Suggested Trade", {
                "scope": __name__,
                "tradeDetail": tradeDetail
            })

        return len(self.tradeDetails) > 0
Пример #53
0
    def _getRules(self):
        connection = sqlite3.connect(pyswing.database.pySwingDatabase)

        query = "SELECT name FROM sqlite_master WHERE type='table' and name like 'Rule %' order by name"

        rules = None

        cursor = connection.cursor()
        try:
            cursor.execute(query)
            rules = cursor.fetchall()
        except sqlite3.OperationalError:
            Logger.log(logging.INFO, "Error Getting Rules", {"scope": __name__})

        connection.close()

        return [(rule[0]) for rule in rules]
Пример #54
0
    def test_deleteFile(self):

        relativeFilePath = "output/test_deleteFile.txt"

        try:
            file = open(relativeFilePath, 'w')
            file.write("Hello!")
            file.close()
        except OSError as osError:
            Logger.log(logging.ERROR, "Cannot Create File", {"scope":__name__, "directory":relativeFilePath})
            Logger.log(logging.DEBUG, "Caught Exception", {"scope":__name__, "exception":str(osError)})

        self.assertTrue(os.path.exists(relativeFilePath))

        deleteFile(relativeFilePath)

        self.assertFalse(os.path.exists(relativeFilePath))