/* This file is part of jTotus. jTotus is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. jTotus is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with jTotus. If not, see <http://www.gnu.org/licenses/>. * */ package org.jtotus.methods; import java.math.BigDecimal; import org.jtotus.common.Helper; import org.jtotus.common.MethodResults; import org.jtotus.network.StockType; /** * @author Evgeni Kappinen */ public class StatisticsFreqPeriod extends TaLibAbstract implements MethodEntry { private int maxPeriod = 20; private boolean debug = false; private static final int POSITIVE = 0; private static final int NEGATIVE = 1; private static final int STILL = 2; private StockType stockType = null; public String getMethName() { return "StatisticsFreqPeriod"; } private int normilize(double tmp) { if (tmp > 0) { return 1; } else if (tmp < 0) { return -1; } return 0; } public int lastTrend(String stockName) { BigDecimal data = null; double table[] = null; int mainDirection = 0; int strikes = 0; if (stockType == null) { stockType = new StockType(); } stockType.setStockName(stockName); for (int i = 0; i < this.getMaxPeriod(); i++) { data = stockType.fetchPastDayClosingPrice(i); if (data == null) { continue; } table = Helper.putAsLastToArray(table, data.doubleValue()); if (table.length < 2) { continue; } strikes = 0; mainDirection = normilize(table[1] - table[0]); for (int y = 1; y < table.length; y++) { double delta = table[y] - table[y - 1]; if (mainDirection != normilize(delta)) { return -1 * mainDirection * strikes; } strikes++; } } return 0; } public int lastTrend(double []table) { int mainDirection = 0; int strikes = 0; if (table.length < 2) { System.err.printf("Warning: no data available for %s\n", this.getClass().getSimpleName()); return Integer.MIN_VALUE; } for (int i = 1; i < this.getMaxPeriod() + 1; i++) { strikes = 0; mainDirection = normilize(table[table.length - i] - table[table.length - i - 1]); for (int y = table.length - 1; y >= 0 ; y--) { double delta = table[y] - table[y - 1]; if (mainDirection != normilize(delta)) { return mainDirection * strikes; } strikes++; } } return 0; } @Override public MethodResults performMethod(String stockName, double[] output) { int trendInDays = 0; int marketStat[][] = null; int direct = 0; MethodResults results = new MethodResults(this.getMethName()); marketStat = statisticsForFreq(output); if (debug) { printResultsToStdout(stockName, marketStat, output.length - 1); } trendInDays = lastTrend(output); if (debug) { System.out.printf("Last trend for :%s is : %d\n", output, trendInDays); } double value = 0.0; if (trendInDays > 0) { value = marketStat[POSITIVE][Math.abs(trendInDays) + 1]; direct = 1; } else if (trendInDays < 0) { value = marketStat[NEGATIVE][Math.abs(trendInDays) + 1]; direct = -1; } else { value = marketStat[STILL][Math.abs(trendInDays) + 1]; direct = 0; } if (debug) { System.out.printf("%s last trend:%d:%d marketstat:%f prop:%f\n", stockName, trendInDays, Math.abs(trendInDays), value, value / (double) output.length); } methodResults.putResult(stockName, direct * (value / (double) (output.length - 1))); return results; } /** * @param output market data */ public int[][] statisticsForFreq(double output[]) { int mainDirection = 0; int strikes = 0; int[][] marketStat = new int[3][getMaxPeriod()]; //Set fist flow if (output.length < 2) { return null; } mainDirection = normilize(output[1] - output[0]); //First direction for (int i = 1; i < output.length; i++) { double delta = output[i] - output[i - 1]; if (debug) { System.out.printf("[%f:%f] delta:%f direct:%d deltaDirection:%d strikes:%d \n", output[i - 1], output[i], output[i] - output[i - 1], mainDirection, normilize(delta), strikes); } if (mainDirection != normilize(delta)) { if (mainDirection > 0) { marketStat[this.POSITIVE][strikes]++; } else if (mainDirection < 0) { marketStat[this.NEGATIVE][strikes]++; } else { marketStat[this.STILL][strikes]++; } mainDirection = normilize(delta); strikes = 1; } else { if (strikes < getMaxPeriod()) { strikes++; } } } if (mainDirection > 0) { marketStat[this.POSITIVE][strikes]++; } else if (mainDirection < 0) { marketStat[this.NEGATIVE][strikes]++; } else { marketStat[this.STILL][strikes]++; } if (debug) { printResultsToStdout("Testing..", marketStat, output.length - 1); } return marketStat; } private float pros(int share, float total) { return ((float) share / total) * 100; } private void printResultsToStdout(String stockName, int[][] marketData, int total_days) { float total_pos = 0.0f; float total_neg = 0.0f; float total_neu = 0.0f; int rowSum = 0; for (int i = 1; i < getMaxPeriod(); i++) { total_pos += marketData[this.POSITIVE][i]; total_neg += marketData[this.NEGATIVE][i]; total_neu += marketData[this.STILL][i]; } System.out.printf("Data for %s\n", stockName); for (int i = 1; i < getMaxPeriod(); i++) { if (marketData[this.POSITIVE][i] != 0 || marketData[this.NEGATIVE][i] != 0 || marketData[this.STILL][i] != 0) { rowSum = marketData[this.POSITIVE][i] + marketData[this.NEGATIVE][i] + marketData[this.STILL][i]; System.out.printf("Up: %d (%.2f of total) (%.2f of Ups) [%.2f of Row] |" + " Down: %d (%.2f) [%.2f] |" + " Still: %d (%.2f) [%.2f] -> %d days in a row\n", marketData[this.POSITIVE][i], pros(marketData[this.POSITIVE][i], total_days), pros(marketData[this.POSITIVE][i], total_pos), pros(marketData[this.POSITIVE][i], (float) rowSum), marketData[this.NEGATIVE][i], pros(marketData[this.NEGATIVE][i], total_neg), pros(marketData[this.NEGATIVE][i], (float) rowSum), marketData[this.STILL][i], pros(marketData[this.STILL][i], total_neu), pros(marketData[this.STILL][i], (float) rowSum), i); } } System.out.printf("total days:%d \n", total_days); } public boolean isCallable() { return true; } /** * @return the maxPeriod */ public int getMaxPeriod() { return maxPeriod; } /** * @param maxPeriod the maxPeriod to set */ public void setMaxPeriod(int maxPeriod) { this.maxPeriod = maxPeriod; } }