Friday, November 16, 2018

QLearning Run With 1 Day Look-ahead Is A Tad Bullish.

In previous versions of the QLearning algo (see previous blog post) I used a 5 day look ahead of the last 5 day trend (simple moving average) . Last night whilst tossing and turning in bed and bothering the wife I thought about the look ahead part and figured that maybe that's cheating a bit. So the database was rebuilt using only a one day look ahead of the next day price. Here are the results of that change.
OEF to cash to stocks iShares SP100 Index
was cash 17.86% 46.43%
was stocks 35.71% 0.00%

53.57% 46.43% bearish




QQQ to cash to stocks Invesco QQQ Trust
was cash 35.71% 25.00%
was stocks 32.14% 7.14%

67.86% 32.14% bearish




TQQQ to cash to stocks ProShares UltraPro QQQ
was cash 25.00% 46.43%
was stocks 17.86% 10.71%

42.86% 57.14% bullish




SQQQ to cash to stocks ProShares UltraPro Short QQQ
was cash 32.14% 39.29%
was stocks 21.43% 7.14%

53.57% 46.43% bullish




QLD to cash to stocks ProShares Ultra QQQ
was cash 21.43% 39.29%
was stocks 25.00% 14.29%

46.43% 53.57% bullish




QID to cash to stocks ProShares UltraShort QQQ
was cash 35.71% 32.14%
was stocks 28.57% 3.57%

64.29% 35.71% bullish




SPY to cash to stocks SPDR SP500
was cash 32.14% 50.00%
was stocks 17.86% 0.00%

50.00% 50.00% toss up




SPXL to cash to stocks Direxion Daily SP500 Bull 3X Shares
was cash 25.00% 39.29%
was stocks 32.14% 3.57%

57.14% 42.86% bearish




SPXS to cash to stocks Direxion Daily SP500 Bear 3X Shares
was cash 21.43% 42.86%
was stocks 32.14% 3.57%

53.57% 46.43% bullish




UPRO to cash to stocks ProShares UltraPro SP500
was cash 28.57% 35.71%
was stocks 32.14% 3.57%

60.71% 39.29% bearish




SPXU to cash to stocks ProShares UltraPro Short SP500
was cash 17.86% 46.43%
was stocks 32.14% 3.57%

50.00% 50.00% toss up

Saturday, November 10, 2018

Still Bearish But SP500 Related Showing Some Bullishness

OEF to cash to stocks iShares SP100 Index
was cash 32.14% 35.71%
was stocks 25.00% 7.14%

57.14% 42.86% bearish




QQQ to cash to stocks Invesco QQQ Trust
was cash 28.57% 32.14%
was stocks 28.57% 10.71%

57.14% 42.86% bearish




TQQQ to cash to stocks ProShares UltraPro QQQ
was cash 32.14% 28.57%
was stocks 21.43% 17.86%

53.57% 46.43% bearish




SQQQ to cash to stocks ProShares UltraPro Short QQQ
was cash 25.00% 42.86%
was stocks 25.00% 7.14%

50.00% 50.00% toss up




QLD to cash to stocks ProShares Ultra QQQ
was cash 35.71% 28.57%
was stocks 28.57% 7.14%

64.29% 35.71% bearish




QID to cash to stocks ProShares UltraShort QQQ
was cash 17.86% 35.71%
was stocks 35.71% 10.71%

53.57% 46.43% bullish




SPY to cash to stocks SPDR SP500
was cash 21.43% 35.71%
was stocks 28.57% 14.29%

50.00% 50.00% toss up




SPXL to cash to stocks Direxion Daily SP500 Bull 3X Shares
was cash 21.43% 32.14%
was stocks 32.14% 14.29%

53.57% 46.43% bearish




SPXS to cash to stocks Direxion Daily SP500 Bear 3X Shares
was cash 14.29% 25.00%
was stocks 50.00% 10.71%

64.29% 35.71% bullish




UPRO to cash to stocks ProShares UltraPro SP500
was cash 28.57% 21.43%
was stocks 32.14% 17.86%

60.71% 39.29% bearish




SPXU to cash to stocks ProShares UltraPro Short SP500
was cash 21.43% 25.00%
was stocks 46.43% 7.14%

67.86% 32.14% bullish

Wednesday, November 7, 2018

Hold On There Bobba Looey - What's With The Bearish Calls.

Both the quasi Monte Carlo and the QLearning models are giving more bearish signs.

MC

OEF to cash to stocks iShares SP100 Index
was cash 0.25 0.14
was stocks 0.36 0.25

0.61 0.39 bearish




QQQ to cash to stocks Invesco QQQ Trust
was cash 0.32 0.21
was stocks 0.39 0.07

0.71 0.29 bearish




TQQQ to cash to stocks ProShares UltraPro QQQ
was cash 0.25 0.14
was stocks 0.50 0.11

0.75 0.25 bearish




SQQQ to cash to stocks ProShares UltraPro Short QQQ
was cash 0.18 0.21
was stocks 0.00 0.61

0.18 0.82 bearish




QLD to cash to stocks ProShares Ultra QQQ
was cash 0.39 0.18
was stocks 0.36 0.07

0.75 0.25 bearish




QID to cash to stocks ProShares UltraShort QQQ
was cash 0.21 0.14
was stocks 0.00 0.64

0.21 0.79 bearish




SPY to cash to stocks SPDR SP500
was cash 0.50 0.04
was stocks 0.32 0.14

0.82 0.18 bearish




SPXL to cash to stocks Direxion Daily SP500 Bull 3X Shares
was cash 0.43 0.00
was stocks 0.36 0.21

0.79 0.21 bearish




SPXS to cash to stocks Direxion Daily SP500 Bear 3X Shares
was cash 0.18 0.14
was stocks 0.00 0.68

0.18 0.82 bearish




UPRO to cash to stocks ProShares UltraPro SP500
was cash 0.43 0.00
was stocks 0.36 0.21

0.79 0.21 bearish




SPXU to cash to stocks ProShares UltraPro Short SP500
was cash 0.14 0.21
was stocks 0.04 0.61

0.18 0.82 bearish

QL

OEF to cash to stocks iShares SP100 Index
was cash 0.21 0.50
was stocks 0.18 0.11

0.39 0.61 bullish




QQQ to cash to stocks Invesco QQQ Trust
was cash 0.32 0.39
was stocks 0.21 0.07

0.54 0.46 bearish




TQQQ to cash to stocks ProShares UltraPro QQQ
was cash 0.25 0.39
was stocks 0.29 0.07

0.54 0.46 bearish




SQQQ to cash to stocks ProShares UltraPro Short QQQ
was cash 0.11 0.50
was stocks 0.32 0.07

0.43 0.57 bearish




QLD to cash to stocks ProShares Ultra QQQ
was cash 0.25 0.39
was stocks 0.32 0.04

0.57 0.43 bearish




QID to cash to stocks ProShares UltraShort QQQ
was cash 0.21 0.39
was stocks 0.32 0.07

0.54 0.46 bullish




SPY to cash to stocks SPDR SP500
was cash 0.21 0.29
was stocks 0.46 0.04

0.68 0.32 bearish




SPXL to cash to stocks Direxion Daily SP500 Bull 3X Shares
was cash 0.21 0.32
was stocks 0.32 0.14

0.54 0.46 bearish




SPXS to cash to stocks Direxion Daily SP500 Bear 3X Shares
was cash 0.14 0.39
was stocks 0.46 0.00

0.61 0.39 bullish




UPRO to cash to stocks ProShares UltraPro SP500
was cash 0.25 0.32
was stocks 0.32 0.11

0.57 0.43 bearish




SPXU to cash to stocks ProShares UltraPro Short SP500
was cash 0.21 0.46
was stocks 0.25 0.07

0.46 0.54 bearish

A Double Moving Average QLearning Program - Java


package QLearning;

import java.io.IOException;
import java.sql.SQLException;
import java.util.TreeMap;

import com.americancoders.TopAndBottomList;
import com.americancoders.dataGetAndSet.GetStockDataUsingSQL;
import com.tictactec.ta.lib.Core;
import com.tictactec.ta.lib.MInteger;

import util.Realign;

/**
 * @author joe mcverry usacoder@gmail.com
 * @since 10-10-2018
 * @version 0.0.10
 *
 *          abstract class QLearner is runnable so we can run multiple tests
 *          concurrently using threads.
 */



/**
 * calls QLearningAlgorithm
 * source code posted https://usacoder.blogspot.com/2018/10/a-java-based-qlearning-algorithm-for.html
 */

public class DoubleMovingAverage extends QLearner {

    TreeMap> maFastTree;
    TreeMap> maSlowTree;

    @Override
    public String getIntervalKey() {
        /**
         * method use to find price, trend and moving average data stored in
         * tree maps
         */
        String key = intervals[0] + ";" + intervals[1];
        return key;
    }

    @Override
    public double getTrend(String symbol, String[] intervals, int i) {
        /**
         * get the trend (5 days), its overridden because some interval keys can
         * be be different
         */
        String key = intervals[1];
        return trendTree.get(symbol).get(key)[i];
    }

    @Override
    public boolean dataHere(String symbol, String intervals[], int position) {
        /**
         * skip overdata from position 0 to moving average period, its
         * overridden becaus some interval keys can be be different
         */
        String key = intervals[1];
        return maSlowTree.get(symbol).get(key)[position] != 0;
    }

    @Override
    public String getAttributeValue(String symbol, String[] intervals, int pos) {

        /**
         * this returns the attribute strings for the simple moving average
         * qlearner price at this position greater Fast MA at same position or
         * price less Fast MA price greater Slow MA or less Slow MA fast MA
         * greater Slow MA or below Slow MA
         */

        String ret = "";
        if (getPrice(symbol, pos) > maFastTree.get(symbol).get(intervals[0])[pos])
            ret += "priceAboveFast";
        else
            ret += "priceBelowFast";
        if (getPrice(symbol, pos) > maSlowTree.get(symbol).get(intervals[1])[pos])
            ret += "-priceAboveSlow";
        else
            ret += "-priceBelowSlow";
        if (maFastTree.get(symbol).get(intervals[0])[pos] > maSlowTree.get(symbol).get(intervals[1])[pos])
            ret += "-fastAboveSlow";
        else
            ret += "-fastBelowSlow";

        return ret;
    }

    /**
     * @param args
     * @throws SQLException
     * @throws IOException
     * @throws NumberFormatException
     */
    public static void main(String[] args) throws NumberFormatException, IOException, SQLException {

        DoubleMovingAverage smas = new DoubleMovingAverage();
        smas.run();
    }

    @Override
    public void run() {

        for (String symbol : QLearner.symbols) {
            /**
             * I use a list of ETFs based on the SP100 and 500 best for symbol
             * is a table with the symbol as key and the data is the best
             * returned value along with the fast and slow parameters
             */
            bestForSymbol.put(symbol, new TopAndBottomList());
            // first load up the run tables for testing
            for (int fast = 4; fast <= 10; fast++) {
                for (int slow = fast + 3; slow <= 20; slow++) {
                    try {
                        add(symbol, fast, slow);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        for (int fast = 4; fast <= 10; fast++) {
            intervals[0] = fast + "";
            for (int slow = fast + 3; slow <= 20; slow++) {
                intervals[1] = slow + "";
                /**
                 * test and run calls the qlearner algorithm building training
                 * data up to a previous date - I use data upto 6 months ago.
                 * the method then runs a simulator using data after the
                 * trainging data stops It will populat the best for symbol
                 * table mentioned above.
                 */
                testAndRun();
            }
        }
        try {
            /**
             * after all is said and don take the best returned value for each
             * symbol and update database with the fast & slow values so the
             * same parameters can be used when making buy sell calls based on
             * the double moving averages
             */
            updateTables("DoubleMA");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public DoubleMovingAverage() {
        priceTree = new TreeMap<>();
        dateTree = new TreeMap<>();
        maFastTree = new TreeMap<>();
        maSlowTree = new TreeMap<>();
    }

    public void add(String sym, int fast, int slow) throws NumberFormatException, IOException, SQLException {

        double price[];
        String dates[];
        double maFast[];
        double maSlow[];

        intervals = new String[2];

        GetStockDataUsingSQL gsd = GetStockDataUsingSQL.getInstance(sym);
        price = gsd.inClose;
        priceTree.put(sym, price);
        dates = gsd.inDate;
        dateTree.put(sym, dates);

        Core core = new Core();

        maFast = new double[gsd.inClose.length];
        TreeMap fastTreeMap = maFastTree.get(sym);
        if (fastTreeMap == null) {
            fastTreeMap = new TreeMap<>();
            maFastTree.put(sym, fastTreeMap);
        }
        fastTreeMap.put(fast + "", maFast);
        MInteger outBegIdx = new MInteger();
        MInteger outNBElement = new MInteger();
        core.sma(0, gsd.inClose.length - 1, gsd.inClose, fast, outBegIdx, outNBElement, maFast);
        Realign.realign(maFast, outBegIdx.value);

        maSlow = new double[gsd.inClose.length];
        TreeMap slowTreeMap = maSlowTree.get(sym);
        if (slowTreeMap == null) {
            slowTreeMap = new TreeMap<>();
            maSlowTree.put(sym, slowTreeMap);
        }
        slowTreeMap.put(slow + "", maSlow);
        outBegIdx = new MInteger();
        outNBElement = new MInteger();
        core.sma(0, gsd.inClose.length - 1, gsd.inClose, slow, outBegIdx, outNBElement, maSlow);
        Realign.realign(maSlow, outBegIdx.value);

        buildTrend(sym, slow + "", gsd.inClose, trendTree);

    }

}