def doAlgSteps(algKey, startStep, stopStep, stats, stckIDs, MaxTrade = False):
    if len(stckIDs) == 1:
        accumulate = True
    else:
        accumulate = False
    alginfo = meTools.memGet(meSchema.meAlg, algKey)
 
    if MaxTrade:
        alginfo.Cash = alginfo.Cash + stats['PandL']
        alginfo.TradeSize = (0.94/len(stckIDs))
    desires = liveAlg.getStepRangeAlgDesires(algKey, alginfo, startStep, stopStep)
    buydelta = meTools.memGet(meSchema.tradeCue, alginfo.BuyCue).TimeDelta
    selldelta = meTools.memGet(meSchema.tradeCue, alginfo.SellCue).TimeDelta

    orderDesires = desires.keys()
    orderDesires.sort()

    for step in range(startStep, stopStep + 1):
        stopRange = 80
        if (step - startStep - 44)%stopRange == 0:
            stats = doStops(step, copy.deepcopy(stats), alginfo, stopRange)
        potentialDesires = [meTools.buildDesireKey(step, algKey, stckID) for stckID in stckIDs]  # must feed stckIDs into func?
        for key in potentialDesires:
            if key in orderDesires:
                currentDesire = eval(desires[key])
                for des in currentDesire:            # Eventually re-do desires[key] to be just dict with 'Symbol' 'Shares' keys.
                    buysell = cmp(currentDesire[des]['Shares'], 0)
                    Symbol = des
                tradeCash, PandL, position = princeFunc.mergePosition(eval(desires[key]), copy.deepcopy(stats['Positions']), step, accumulate)
                cash = tradeCash + copy.deepcopy(stats['Cash'])
                if buysell == -1:
                    timedelta = selldelta
                    lastTradeStep = stats['lastSell']
                elif buysell == 1:
                    timedelta = buydelta
                    lastTradeStep = stats['lastBuy']

                if cash > 0 and lastTradeStep <= step - timedelta:
                    if buysell == -1:
                        stats['lastSell'] = step
                    elif buysell == 1:
                        stats['lastBuy'] = step
                    stats['CashDelta'].appendleft({'Symbol' : Symbol,
                                                   'buysell' : buysell,
                                                   'value'   : tradeCash,
                                                   'PandL'   : PandL,
                                                   'step'    : step})

                    if len(stats['CashDelta']) > 800:
                        stats['CashDelta'].pop()
                    stats['Cash'] = cash
                    stats['PandL'] += PandL
                    stats['Positions'] = position
    return stats
def doStops(step, statDict, alginfo, stopRange, scaleFactor = 0.0):
    from random import random

    stopDesires = []
    stckKeys = [str(stckID) + '_' + str(step) for stckID in [1,2,3,4]]
    stocks = memGetStcks(stckKeys)
    stckQuotes = {}
    for stock in stocks:
        if stock is None:
            return statDict
        else:
            stckQuotes[meTools.getStckSymbol(stock.ID)] = stock.quote
    for pos in statDict['Positions']:
        stckID = meTools.getStckID(pos)
        stckDeltas = calculateDeltas(stckID,step)
        shares = statDict['Positions'][pos]['Shares']
        longshort = cmp(shares,0)                                  # -1 for short, +1 for long
        stckQuote = stckQuotes[pos]
        offsetDesire = meSchema.desire(Symbol = pos,
                                       Quote = stckQuote,
                                       CueKey = '0000')
        dictDesire = convertDesireToDict(offsetDesire, -1*longshort, alginfo.TradeSize, alginfo.Cash, -1*shares)
        
        # Now only using maxmin deviations for stops.
        maxDevStop, minDevStop = getMaxMinDevMeans(stckDeltas)
        # Using scaleFactor for metaAlgs. Moves stop 40% closer to 1.0

        stopLoss = statDict['Positions'][pos]['StopLoss']
        stopProfit = statDict['Positions'][pos]['StopProfit']
        if longshort == 1:
            if stckQuote < stopLoss or stckQuote > stopProfit:
                stopDesires.append(dictDesire)
            else:
                stopLoss = max(statDict['Positions'][pos]['StopLoss'], stckQuote*minDevStop)
                if stopProfit > 1.15*statDict['Positions'][pos]['Price']:
                    stopPrice = stckQuote*(maxDevStop - ((maxDevStop-1)*scaleFactor))
                    stopProfit = min(statDict['Positions'][pos]['StopProfit'], stopPrice)
        elif longshort == -1:
            if stckQuote > stopLoss or stckQuote < stopProfit:
                stopDesires.append(dictDesire)
            else:
                stopLoss = min(statDict['Positions'][pos]['StopLoss'], stckQuote*maxDevStop)
                if stopProfit < 0.85*statDict['Positions'][pos]['Price']:
                    stopPrice = stckQuote*(minDevStop + ((1-minDevStop)*scaleFactor))
                    stopProfit = max(statDict['Positions'][pos]['StopProfit'], stopPrice)
        statDict['Positions'][pos]['StopLoss'] = stopLoss
        statDict['Positions'][pos]['StopProfit'] = stopProfit
    for stop in stopDesires:
        tradeCash, PandL, position = princeFunc.mergePosition(eval(stop), copy.deepcopy(statDict['Positions']), step, True)
        cash = tradeCash + copy.deepcopy(statDict['Cash'])
        Symbol = eval(stop).keys()[0]
        buysell = cmp(eval(stop)[Symbol]['Shares'], 0)
        statDict['CashDelta'].appendleft({'Symbol'  : Symbol,
                                          'buysell' : str(buysell) + '_stop',
                                          'value'   : tradeCash,
                                          'PandL'   : PandL,
                                          'step'    : step})
        if len(statDict['CashDelta']) > 800:
            statDict['CashDelta'].pop()
        statDict['Cash'] = cash
        statDict['PandL'] += PandL
        statDict['Positions'] = position
    return statDict