/*
 * Copyright (c) 2015, StrategyQuant - All rights reserved.
 *
 * Code in this file was made in a good faith that it is correct and does what it should. 
 * If you found a bug in this code OR you have an improvement suggestion OR you want to include 
 * your own code snippet into our standard library please contact us at:
 * http://tasks.strategyquant.com/projects/snippets/
 *
 * This code can be used only within StrategyQuant products. 
 * Every owner of valid (free, trial or commercial) license of any StrategyQuant product 
 * is allowed to freely use, copy, modify or make derivative work of this code without limitations,
 * to be used in all StrategyQuant products and share his/her modifications or derivative work 
 * with the StrategyQuant community.
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES 
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *  
 */
package com.strategyquant.extend.StatValues;

import com.strategyquant.lib.results.SQOrder;
import com.strategyquant.lib.results.SQOrderList;
import com.strategyquant.lib.results.SQStats;
import com.strategyquant.lib.results.StatValue;
import com.strategyquant.lib.results.StatsConst;
import com.strategyquant.lib.results.StatsTypeCombination;
import com.strategyquant.lib.settings.SQSettings;
import com.strategyquant.lib.utils.SQUtils;

public class ConsecutivesValues extends StatValue {
    int totalConsecWins, totalConsecLosses;
    int consecWinsPeriods, consecLossesPeriods;
    int consecWins, consecLosses;
    int maxConsecWins, maxConsecLosses;
    int lastOrderWas;
		
	@Override
	public void initCompute(SQStats stats, StatsTypeCombination combination, SQOrderList ordersList, SQSettings settings, SQStats statsLong, SQStats statsShort) throws Exception {
	    totalConsecWins = 0;
	    totalConsecLosses = 0;
	    consecWinsPeriods = 0;
	    consecLossesPeriods = 0;
	    consecWins = 0;
	    consecLosses = 0;
	    maxConsecWins = 0;
	    maxConsecLosses = 0;
	    lastOrderWas = 0;
	}

	@Override
	public void computeForOrder(SQStats stats, StatsTypeCombination combination, SQOrder order, SQSettings settings, SQStats statsLong, SQStats statsShort) throws Exception {
		if(order.PL > 0) {
			// process consecutive orders
            consecWins++;
            if(lastOrderWas < 0) {
                // last order was not win (it was loss), so reset the counter
                // and set consecutive losses data
                lastOrderWas = 1; // win
                if(maxConsecLosses < consecLosses) {
                    maxConsecLosses = consecLosses;
                }
                totalConsecLosses += consecLosses;
                consecLossesPeriods++;
                consecLosses = 0;
            }
            lastOrderWas = 1; // win
		} else {
            // process consecutive orders
            consecLosses++;
            if(lastOrderWas > 0) {
                // last order was not loss (it was win), so reset the counter
                // and set consecutive wins data
                if(maxConsecWins < consecWins) {
                    maxConsecWins = consecWins;
                }
                totalConsecWins += consecWins;
                consecWinsPeriods++;
                consecWins = 0;
            }
            lastOrderWas = -1; // loss
		}		
	}

	@Override
	public void endCompute(SQStats stats, StatsTypeCombination combination, SQOrderList ordersList, SQSettings settings, SQStats statsLong, SQStats statsShort) throws Exception {
        // consecutive wins stats        
        if(consecWins > 0) {
            // set consecutive wins data
            if(maxConsecWins < consecWins) {
                maxConsecWins = consecWins;
            }
            totalConsecWins += consecWins;
            consecWinsPeriods++;
        }
        
        // consecutive losses stats
        if (consecLosses > 0) {
            // set consecutive losses data
            if (maxConsecLosses < consecLosses) {
                maxConsecLosses = consecLosses;
            }
            totalConsecLosses += consecLosses;
            consecLossesPeriods++;
        }
        
		stats.set(StatsConst.MAX_CONSEC_WINS, maxConsecWins);
		stats.set(StatsConst.MAX_CONSEC_LOSS, maxConsecLosses);
		
		double avgConsecWin = SQUtils.safeDivide(totalConsecWins, consecWinsPeriods);
		double avgConsecLoss = SQUtils.safeDivide(totalConsecLosses, consecLossesPeriods);
		
		stats.set(StatsConst.AVG_CONSEC_WIN, SQUtils.round2(avgConsecWin));
		stats.set(StatsConst.AVG_CONSEC_LOSS, SQUtils.round2(avgConsecLoss));
	}


}