// Downloaded From https://www.WiseStockTrader.com
/*-------------------------------------
Buy        = Buy when price has showed upward momentum
             by moving from tradeActivationPrice to buyPriceStart.
Sell       = Sell at SellPrice.
myStopLoss = Sell at myStopLoss price.

Notes:
 - Scratch system to understand AB
 - Curve fitting at its worst. (so don't use, duh.)
 
Warnings:
You can not have more Buy points than you have bars of data.

-------------------------------------*/

// Configuration
// writeLog = TRUE;
// doLoop = FALSE;
writeLog = True;
doLoop = True;

// Housekeeping
_TRACE("!CLEAR!"); // Clear the Trace window
SetOption( "ActivateStopsImmediately", True );
SetOption( "AllowSameBarExit", False );
SetOption( "CommissionAmount", .005 );
SetOption( "CommissionMode", 3 );
SetOption( "ExtraColumnsLocation", 1 );
SetOption( "InitialEquity", 100000 );
SetOption( "PortfolioReportMode", 1 );
SetOption( "PriceBoundChecking", False);
SetOption( "RefreshWhenCompleted", True );
SetOption( "RequireDeclarations", False );
SetOption( "ReverseSignalForcesExit", False );
SetOption( "SeparateLongShortRank", True );
SetPositionSize( 10000, spsValue );
SetTradeDelays(0,0,0,0);

y = Year(); 
m = Month(); 
d = Day(); 
r = Hour();
e = Minute();
n = Second();

// Tried both with and without backtestmode
SetBacktestMode( backtestRegularRawMulti );

if ( writeLog == True )
{
  fhLog = fopen( "e:\\AmiBroker\\logs\\firstSystemLog.txt", "w");
  if ( fhLog == 0 )
  {
    _TRACE("Blew the file open");
    writeLog = False;
  }
}

if ( writeLog == True )
{
  op = StrFormat("\n\n********* Symbol : ") + Name() +  StrFormat(" *********\n");
  fputs( op, fhLog );
}

// Set static values
symbolsLow       = 10000000;
symbolsHigh      = 0;

symbolsHigh = LastValue( Highest( High ) );
symbolsLow = LastValue( Lowest( Low ) );
_TRACE( "symbolsLow - lastvalue: " + symbolsLow );
_TRACE( "symbolsHigh: " + symbolsHigh );

pctMin  = .01;
pctMax  = .10;  //.10
pctStep = .01;
buyStep = .01; // cents

// Manipulate statics
buyPriceMin = int( ( symbolsLow * ( 1 - pctMax ) ) * 100 ) / 100;
buyPriceMax  = ( int( symbolsHigh * 100 ) + 1 ) / 100;
_TRACE( "buyPriceMin: " + buyPriceMin );
_TRACE( "buyPriceMax: " + buyPriceMax );

if ( writeLog == True )
{
  op = StrFormat("Setup Vars:\nsymbolsLow-%.4f, symbolsHigh-%.4f, buyPriceMin-%.4f, buyPriceMax-%.4f\n", symbolsLow,symbolsHigh,buyPriceMin,buyPriceMax );
  fputs( op, fhLog );
}

// Optimization Vars (x = Optimize( "description", default, min , max, step );)
// buyPriceStart = Optimize( "BuyPrice", 36, buyPriceMin, symbolsLow, buyStep );
// profitPctChange = Optimize( "ProfPctChg", .06, pctMin, pctMax, pctStep );
// stopLossPctChange = Optimize( "StLoPctChg", .02, pctMin, pctMax, pctStep );
// tradeActPctChange = Optimize( "TrActPctChg", .05, pctMin, pctMax, pctStep );
buyPriceStart = 17.05;
profitPctChange = 0.08;
stopLossPctChange = Optimize( "StLoPctChg", .06, .06, .10, pctStep );
tradeActPctChange = Optimize( "TrActPctChg", .07, .04, .09, pctStep );
if ( writeLog == True )
{
  op = StrFormat("Optimization Vars:\nbuyPriceStart-%.4f, profitPctChange-%.4f, stopLossPctChange-%.4f, tradeActPctChange-%.4f\n\n", buyPriceStart,profitPctChange,stopLossPctChange,tradeActPctChange );
  fputs( op, fhLog );
}

// Setup Arrays
Sell = False;  // Initialize "Sell" array....
Buy = False;  // Initialize "Buy" array....
openPos = False; // No open positions to start with
lastLow = False; // Just initialize it
buyPrices = 0;
tradeActivationPrices = 0;
myStopLosss = 0;
sellPrices = 0;

// Setup Single value vars
numBuyPoints = 0;

// Create the first Activation, Buy, Stop, Profit points array
buyPrices[0]             = buyPriceStart;
tradeActivationPrices[0] = buyPriceStart * ( 1 - tradeActPctChange );
myStopLosss[0]           = buyPriceStart * ( 1 - stopLossPctChange );
sellPrices[0]            = buyPriceStart * ( 1 + profitPctChange );
lastLow[0]               = 10000000; // Set insanely high so first Low sets it
if ( writeLog == True )
{
  op = StrFormat("BuyPrices: [0] Buy-%.4f, Activate-%.4f, Stop-%.4f, Profit-%.4f\n", buyPrices[0],tradeActivationPrices[0],myStopLosss[0],sellPrices[0] );
  fputs( op, fhLog );
}

for ( i = 1; i < BarCount; i++ ) // Create the rest of Activation, Buy, Stop, Profit points array
{
  buyPrices[i]             = int ( buyPrices[i-1] * ( 1 + profitPctChange ) * 100 ) / 100;
  tradeActivationPrices[i] = int ( buyPrices[i] * ( 1 - tradeActPctChange ) * 100 ) / 100;
  myStopLosss[i]           = int ( buyPrices[i] * ( 1 - stopLossPctChange ) * 100 ) / 100;
  sellPrices[i]            = int ( buyPrices[i] * ( 1 + profitPctChange ) * 100 ) / 100;
  lastLow[i]               = 10000000; // Set insanely high so first Low sets it
  numBuyPoints             = numBuyPoints + 1;
  if ( writeLog == True )
  {
    op = StrFormat("BuyPrices: [%g] Buy-%.4f, Activate-%.4f, Stop-%.4f, Profit-%.4f\n", i,buyPrices[i],tradeActivationPrices[i],myStopLosss[i],sellPrices[i] );
    fputs( op, fhLog );
  }

  if ( buyPrices[i] > buyPriceMax ) // last Buy point is never accessed, per below
  {
    break;
  }
}

if ( doLoop == True )
{

// Start this Pig...
for ( i = 0; i < BarCount; i++ ) // Loop over all bars in the chart
{
  for ( j = 0; j < numBuyPoints; j++ ) // Loop over all Buy points
  {
    if ( openPos[j] ) // Have an open position, check to sell it
    {
      if ( Low[i] < myStopLosss[j] ) // Check for Stops
      {
        if ( Sell[i] ) // ah crap, we've Sold on this bar already
        {
          // Report it, but do nothing else, next Close will close both...
          if ( writeLog == True )
          {
            op = "CRAP - Double Sell, Stop!\n";
            op = op + StrFormat(",%02.0f-%02.0f-%02.0f,%02.0f:%02.0f:%02.0f", y[ i ], m[ i ], d[ i ], r[ i ], e[ i ], n[ i ] );
            op = op + StrFormat("j=%g, High-%.4f, Low-%.4f, lastLow-%.4f, myStopLoss-%.4f\n", j,High[ i ],Low[ i ],lastLow[j],myStopLosss[j] );
            fputs( op, fhLog );
          }
        }
        else
        {
          SellPrice[i] = myStopLosss[j];
          Sell[i] = True;
          openPos[j] = False; // No longer have open position
          lastLow[j] = IIf( Close[i] < SellPrice[i], Close[i], SellPrice[i] ); // ReSet lastLow[j] for Buy Check
          if ( writeLog == True )
          {
            op = Name() + ",StopLoss";
            op = op + StrFormat(",%02.0f-%02.0f-%02.0f,%02.0f:%02.0f:%02.0f", y[ i ], m[ i ], d[ i ], r[ i ], e[ i ], n[ i ] );
            op = op + StrFormat(",%g,%.4f,%.4f\n", j, buyPrices[j], SellPrice[i] );
            fputs( op, fhLog );
          }
        }
      }
      else
      {
        if ( High[i] > sellPrices[j] ) // Check for Profits
        {
          if ( Sell[i] ) // ah crap, we've Sold on this bar already
          {
            // Report it, but do nothing else
            if ( writeLog == True )
            {
              op = "CRAP - Double Sell, Profit!\n";
              op = op + StrFormat(",%02.0f-%02.0f-%02.0f,%02.0f:%02.0f:%02.0f", y[ i ], m[ i ], d[ i ], r[ i ], e[ i ], n[ i ] );
              op = op + StrFormat("j=%g, High-%.4f, Low-%.4f, lastLow-%.4f, myStopLoss-%.4f\n", j,High[ i ],Low[ i ],lastLow[j],myStopLosss[j] );
              fputs( op, fhLog );
            }
          }
          else
          {
            SellPrice[i] = sellPrices[j];
            Sell[i] = True;
            openPos[j] = False; // No longer have open position
            lastLow[j] = IIf( Close[i] < SellPrice[i], Close[i], SellPrice[i] ); // ReSet lastLow[j] for Buy Check
            if ( writeLog == True )
            {
              op = Name() + ",Profit";
              op = op + StrFormat(",%02.0f-%02.0f-%02.0f,%02.0f:%02.0f:%02.0f", y[ i ], m[ i ], d[ i ], r[ i ], e[ i ], n[ i ] );
              op = op + StrFormat(",%g,%.4f,%.4f\n", j, buyPrices[j], SellPrice[i] );
              fputs( op, fhLog );
            }
          }
        }
      }
    }
    else // Nothing open on this BuyPoint, see if we can buy something
    {
      if (     ( lastLow[j] < tradeActivationPrices[j] )
           AND ( High[i] > buyPrices[j] )
           AND ( buyPrices[j] > Low[i] )
         )
      {
        if ( Buy[i] ) // ah crap, we've bought on this bar already
        {
          // Report it, but do nothing else
          if ( writeLog == True )
          {
            op = "CRAP - We lost a Buy!\n";
            op = op + StrFormat(",%02.0f-%02.0f-%02.0f,%02.0f:%02.0f:%02.0f", y[ i ], m[ i ], d[ i ], r[ i ], e[ i ], n[ i ] );
            op = op + StrFormat("j=%g, BuyPrice-%.4f, High-%.4f, Low-%.4f, lastLow-%.4f, tradeActivationPrices-%.4f\n", j,buyPrices[j],H[ i ],L[ i ],lastLow[j],tradeActivationPrices[j] );
            fputs( op, fhLog );
          }
        }
        else
        {
          BuyPrice[i] = buyPrices[j];
          Buy[i] = True;
          openPos[j] = True; // Now have an open position
          if ( writeLog == True )
          {
            op = Name() + ",Bought";
            op = op + StrFormat(",%02.0f-%02.0f-%02.0f,%02.0f:%02.0f:%02.0f", y[ i ], m[ i ], d[ i ], r[ i ], e[ i ], n[ i ] );
            op = op + StrFormat(",%g,%.4f\n", j, buyPrices[j] );
            fputs( op, fhLog );
          }
        }
      }
      if (    ( lastLow[j] > Close[i] )
           OR ( lastLow[j] > BuyPrice[i] )
         )
      {
        lastLow[j] = IIf( BuyPrice[i] > Close[i] , Close[i] , BuyPrice[i] );
      }
    }
  }
}
}

if ( writeLog == True )
{
  fclose( fhLog );
}