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
TreeMap
@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
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
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);
}
}
No comments:
Post a Comment