.

Trend Continuation Breakout - Amibroker AFL Code

Click Image To Enlarge. Please Rate And Comment.

Trend Continuation Breakout

_N(SectionName = "Trend Continuation Breakout AFL");
_N(Ver = "Ver1_0"); 

_SECTION_BEGIN(SectionName);  
EnableTextOutput(False); // prevents incidental text from being displayed in the interpretation
Filename = StrLeft(_DEFAULT_NAME(),StrLen(_DEFAULT_NAME())-2) + " " + Ver; // the name of the program and is displayed on the title line
// CAUTION: VarPfx is used to make the static variables unique tp prevent bizarre results if you use multiple versions of the trading program simultaneously. 
VarPfx = Filename + Ver + Name();  

_N(Title = Filename + StrFormat(" - {{DATE}} \nOpen %g, Hi %g, Lo %g, Close %g Vol %g " + " {{VALUES}}", O, H, L, C, V ));
RequestTimedRefresh(1);
SetChartOptions(0, chartShowDates); 

pAutoTrading   = ParamToggle("AutoTrade", "Off|Running");     // turns auto trading on and off
Pause    = ParamToggle("Pause trading", "Run|Pause");  // pause trading
DebugOn    = ParamToggle("DebugView","Off|Running",0);   // Dumps trade data to an output window
closetime   = Param("Close time (hhmmss)", 230000, 0, 245959, 1500);   // end trading at the time specified

// The chart period below must agree with the chart before AutoTrading will connect to TWS.
// the following lines define the acceptable periods that auto trading will work with. 
// To add a period simply add the period to the existiung ParmList separated by a comma AND then add an interval test to the IF statement.
ChartPeriod  = ParamList("Chart Period", "1,3,5,7,10,15,20,30,Hour,Day", 0); // chart period must agree with this setting for auto trading to work
if( ( Interval() == 60      AND ChartPeriod == "1" )    OR 
 ( Interval() == 60 * 3    AND ChartPeriod == "3" )   OR
 ( Interval() == 60 * 5    AND ChartPeriod == "5" )   OR
 ( Interval() == 60 * 7    AND ChartPeriod == "7" )   OR
 ( Interval() == 60 * 10  AND ChartPeriod == "10" )   OR 
 ( Interval() == 60 * 15    AND ChartPeriod == "15" )   OR
 ( Interval() == 60 * 20    AND ChartPeriod == "20" )   OR
 ( Interval() == 60 * 30    AND ChartPeriod == "30" )   OR
 ( Interval() == inHourly  AND ChartPeriod == "Hour" )  OR  
 ( Interval() == inDaily  AND ChartPeriod == "Day" )   )  IntervalOK = True; 
else IntervalOK = False;

pContracts  = Param("Contracts", 100, 1, 1000000, 1);   // definethe default number of contracts to order
OrderType  = ParamList("Order type", "STP,LMT,MKT", 2);  // select type of ofder to send
tick    = Param("Tick size", 0.01, 0.0, 10.0, 0.1);  // amount from current price the stop order will be set
tMult   = Param("Tick multiplier", 100, 1, 1000, 1);  // tick * multiplier is used in placeOrder
tickMult  = tick * tMult;

// The symbol on the chart must agree with the symbol selected from this list before AutoTrading will connect to TWS
// Note on modifyin this. The symbol must match exactly what is in the AB symbol directory. 
// You can see below that ZG has spaces and the exact number of spaces is required. 
// To add a new line just copy a line and replace the things between the "..." with the new symbol.
// The last line ends with "); and that is required so don't mess it up.
// To change the ticker list you may remove a line but refer to ParamList if you have trouble. The spacing has to be exactly what the AB database has.
// The ticker list is a string separated by commas. If you separate them so they fit on another line you must close the string, add a + to indicate
// the string continues on the next line. The string must be closed with a " and the ParamList must be closed with a );

sTicker = ParamList("Symbol to trade", "IBM,MSFT,IWM,QQQQ-SMART-STK,GLD-SMART-STK,FXP", 2);

ManualBuy   = ParamTrigger("Manual buy", "Buy");        // allows user to buy the default number of contracts
ManualSell   = ParamTrigger("Manual Sell", "Sell");       // allows user to sell the default number of contracts
CancelAll    = ParamTrigger("Cancel all pending orders", "Cancel all");  // user can cancel all orders that have not been filled
CloseAll    = ParamTrigger("Close all", "Close all");       // cancel all pending orders and close all open positions

Reset     = ParamTrigger("Reset", "Reset");         // resets the auto trading variables 

StaticVarSet(VarPfx + "AutoTrading", pAutoTrading );

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ###############      Initilization      Initilization       Initilization       Initilization       Initilization     ######################################## 
// ##############################################################################################################################################################
// ##############################################################################################################################################################

sysTime = Now(4); // time offset from New York
sysTimeStr =  NumToStr(SysTime, 1.0, False);
barTime = TimeNum();

// assign values to the following constants
// trigger states used by the program
fNone   = 0; // no orders are being processed
mCancel  = 1; // the user has manually selected cancel all open orders
mClose  = 2; // the user has manually selected close all trades
mBuy   = 3; // the user has manually placed a buy order
mSell   = 4; // theuser has manually placed a sell order
pBuy   = 5; // the users system has generated a buy order 
pSell   = 6; // the users system has generated a sell order 
pShort  = 7; // the users system has generated a short order 
pCover  = 8; // the users system has generated a cover order

// order states set by the program
ordNone   = 20;  // there are no open orders being processed
ordCancelBuy  = 21; // an open buy order is being cancelled and is waiting for a "Cancelled" status from TWS 
ordCancelSell = 22; // an open sell order is being cancelled and is waiting for a "Cancelled" status from TWS  
ordSell   = 23; // an open sell order is being processed and is waiting for a "Filled" status from TWS   
ordBuy   = 24; // an open buy order is being processed and is waiting for a "Filled" status from TWS    
ordCover   = 25; // an open cover order is being processed and is waiting for a "Filled" status from TWS    
ordShort   = 26; // an open short order is being processed and is waiting for a "Filled" status from TWS    
ordCancelAll  = 27; // a cancel all order is being processed and is waiting for a "Cancelled" status from TWS    
ordCloseAll  = 28; 
ordManBuy   = 29; // a manual buy order is being processed and is waiting for a "Filled" status from TWS    
ordManSell  = 30; // a manual sell order is being processed and is waiting for a "Filled" status from TWS    
 
// initializes the static variables when the program starts and when the user presses Reset.
if (Reset OR Nz(StaticVarGet(VarPfx + "SystemInitialized"), True)) // init static vars when indicator starts
 {
 StaticVarSet(VarPfx + "SystemInitialized", True);
// pause = True; // used to artifically pause the system on init. 

 // initialize auto trading vars
 StaticVarSet(VarPfx + "OrderState", OrdNone);     // contains the order state being processed, normal is none
 StaticVarSetText(VarPfx + "ordID", "");     // an active order being processed, blank when no orders are active
 StaticVarSet(VarPfx + "GetStatus", False);   // a flag informs the program that statis is being requested for an active order
 StaticVarSet(VarPfx + "WaitForConfirm",  False); // waiting for the number of contracts to agree with the order that was placed 
 StaticVarSetText(VarPfx + "EOD", "");     //  used to control order processing at the close of trading hours
} // end of power up or reset initialize

// make variables available to the system and trading code
OrderState   = StaticVarGet(VarPfx + "OrderState");   // the current order state
numPositions   = Nz(StaticVarGet(VarPfx + "numPositions")); // the number of positions currently held on TWS
GetStatus    = StaticVarGet(VarPfx + "GetStatus");   // the condition of the status flag, true if waiting for status from TWS
ordID     = StaticVarGetText(VarPfx + "ordID");   // ID of the order beign processed
WaitForConfirm  = StaticVarGet(VarPfx + "WaitForConfirm"); // flag used to tell the program to wait for TWS to update the number of positions
LastC     = LastValue(Close);         // this is the last tick that was received from the broker data feed 
errorMsg    = "None";           // used to hold the TWS error message

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ################################     Functions     Functions     Functions     Functions     Functions     Functions    ######################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################


// converts the trade states to displayable text
function fCvtState(s) // conberts the states to strings for file or trace
{
 temp = "";
 // prog trigger states 
 if(s==fNone)      temp = "NoTrigger"; 
 else if(s==pBuy)     temp = "ProgBuy"; 
 else if(s==pSell)    temp = "ProgSell"; 
 else if(s==pShort)    temp = "ProgShort"; 
 else if(s==pCover)    temp = "ProgCover"; 
 // order states
 else if(s==ordNone)    temp = "OrdNone"; 
 else if(s==ordBuy)    temp = "OrdBuy"; 
 else if(s==ordSell)    temp = "OrdSell"; 
 else if(s==ordShort)   temp = "OrdShort"; 
 else if(s==ordCover)   temp = "OrdCover"; 
 else if(s==ordCancelBuy)  temp = "OrdCancelBuy";  
 else if(s==ordCancelSell)  temp = "OrdCancelSell"; 
 else if(s==ordCancelAll)  temp = "OrdCancelAll"; 
 else if(s==ordCloseAll)  temp = "OrdCloseAll"; 
 else if(s==ordManBuy)   temp = "ordManBuy";
 else if(s==ordManSell)   temp = "OrdManSell"; 
 // manual triggers
 else if(s==mCancel)    temp = "Cancel"; 
 else if(s==mClose)    temp = "CloseAll"; 
 else if(s==mBuy)     temp = "ManBuy"; 
 else if(s==mSell)    temp = "ManSell"; 
 // error state
 else 
 { 
  temp = "Invalid state"; 
  if(DebugOn) _TRACE("#, Invalid state=" + NumToStr(s, 1.0)); 
 }
 return temp;
}

// take hhmmss string and convert to hh:mm:ss
function fFormatTime(time) 
{
 tFmt = "";
 Len = StrLen(time);
 if(Len == 5) tFmt = StrLeft(time,1) + ":" + StrMid(time,1,2) + ":" + StrRight(time, 2); 
 else tFmt = StrLeft(time,2) + ":" + StrMid(time,2,2) + ":" + StrRight(time, 2); 
 return tFmt;
}

// this handles the errors returned on the GetStatus command. 
function fErrorProcessor(msg)
{
 msgid = "";
 if(StrLeft(msg, 2) == "ID")
 {
  offset1 = StrFind(msg, "Error ");
  temp = StrMid(msg, offset1 + 5, offset1 + 5);
  Offset2 = StrFind(temp, ".");
  msgid = StrLeft(temp, Offset2 - 1); 
  if(DebugOn)  _TRACE("#, ErrorMessage = " + msgid);
 }
 return msgid;
}


if(DebugOn)  _TRACE("#, Post Init A, Positions=" + NumToStr(StaticVarGet(VarPfx + "numPositions"), 1.0) + 
 ", GetStatus=" + NumToStr(GetStatus, 1.0) + ", OrderState=" + fCvtState(OrderState) + ", OrderID=" + ordID + 
 ", WaitForConfirm=" + NumToStr(WaitForConfirm, 1.0)); 

_SECTION_END(); 

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ###################    Trading system indicators         Trading system indicators         Trading system indicators         #####################
// ###################    This section of the code uses AB indicators to define the trade timing.                                           #####################
// ##############################################################################################################################################################
// ##############################################################################################################################################################
_SECTION_BEGIN("System"); 

// ##############################################################################################################################################################
// ################  System Parameters
// ##############################################################################################################################################################
Buy = Sell = Short = Cover = 0; // make sure all arrays are set empty

// ##############################################################################################################################################################
// ################  Signal calculations - add your indicator and calculations here
// ##############################################################################################################################################################

pWMA1  = Param("WMA 1 period", 6, 1, 20, 1);
pWMA2  = Param("WMA 2 period", 7, 1, 20, 1);
fMA1  = WMA(C, pWMA1); // calculate MA 1
fMA2  = WMA( (Open + Close)/2, pWMA2); // original


Buy    = fMA1 > fMA2; 
Short   = fMA2 > fMA1;  
Sell   = Short;
Cover    = Buy; 

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// #####################    PLOT INDICATORS    PLOT INDICATORS    PLOT INDICATORS     PLOT INDICATORS     PLOT INDICATORS      ##################################
// #####################     Change the following lines to display your system as you see fit.          ##################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################

Plot(C,   "", colorBlack, ParamStyle( "Price Style", styleBar, maskPrice ) );
Plot(fMA1, "\nMA1(" + NumToStr(pWMA1, 1.0) + ")", colorRed);     // plot the MA lines
Plot(fMA2, "\nMA2(" + NumToStr(pWMA2, 1.0) + ")", colorRed,  styleDashed); // plot the MA lines

PlotShapes(Buy  * shapeUpArrow,    colorGreen,  0, L, -5 );
PlotShapes(Sell  * shapeDownArrow,   colorRed,   0, H, -5 );
PlotShapes(Short * shapeHollowDownArrow, colorRed,   0, H, -20 );
PlotShapes(Cover * shapeHollowUpArrow,  colorGreen,  0, L, -20 );

_SECTION_END(); 

_SECTION_BEGIN(SectionName + "AT"); // Dont change anything in this section unless you know exactly what you are doing.

// ##############################################################################################################################################################
// ################  DO NOT CHANGE THE NEXT 4 LINES -- last values changes the array signal to a binary signal to provide a trigger for the auto trade logic
// ##############################################################################################################################################################

// displays the signal value in the interpretation window
printf("\nBuy = "  + NumToStr(Buy, 1.0) + 
  "  Sell = "  + NumToStr(Sell,  1.0) + 
  "  Short = "  + NumToStr(Short, 1.0) + 
  "  Cover = "  + NumToStr(Cover, 1.0) + "\n");

BuyInd  = LastValue(Buy);  // convert the buy signal to a pulse used by the trading logic
ShortInd   = LastValue(Short); // convert the short signal to a pulse used by the trading logic
SellInd  = LastValue(Sell); // convert the sell signal to a pulse used by the trading logic 
CoverInd = LastValue(Cover); // convert the cover signal to a pulse used by the trading logic

if(DebugOn)  _TRACE("#, Indicators 2, Static, BuyInd = " + NumToStr(BuyInd, 1.0) + 
   ", SellInd = "  + NumToStr(SellInd,  1.0) + 
   ", ShortInd = "  + NumToStr(ShortInd, 1.0) + 
   ", CoverInd = "  + NumToStr(CoverInd, 1.0) );

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ######################################      MANUAL BUY      MANUAL BUY    MANUAL BUY     MANUAL BUY      MANUAL BUY        ###################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################

function fManBuyPositions(ib, oState, OID, positions) 
{
 if(DebugOn)  _TRACE("#, ManBuy top, positions=" + NumToStr(positions, 1) + ", contracts=" + NumToStr(pContracts, 1));    
 newState = oState; 
 // this function closes all open trades
 orderID = "";
 orderID = ib.PlaceOrder(sTicker, "Buy", pContracts, "MKT", 0, 0, "GTC", True, tickMult, "outsideRTH");
 if(orderID != "")
 {
  ordType = "ManBuy";
  newState = ordManBuy; 
  StaticVarSet(VarPfx + "TargetPositions", positions + pContracts);
  StaticVarSetText(VarPfx + "ordID", orderID );
  StaticVarSet(VarPfx + "GetStatus", True);
  StaticVarSet(VarPfx + "WaitForConfirm",  True); 
  if(DebugOn)  _TRACE("#, ManBuy " + ordType + ", " + fFormatTime(sysTimeStr) + ", OrderID" + orderID  + ", OrderState=" + fCvtState(newState) + 
   ", Close=" + NumToStr(LastValue(Close), 1.2));  
 }
 return newState; // return the type of order that was made
}

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// #################################    MANUAL  SELL     MANUAL  SELL     MANUAL  SELL     MANUAL  SELL     MANUAL  SELL      ###################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################

function fManSellPositions(ib, oState, OID, positions) // we are neither long or short
{
 if(DebugOn)  _TRACE("#, ManSel1 top, positions=" + NumToStr(positions, 1) + ", contracts=" + NumToStr(pContracts, 1));    
 newState = oState; 
 orderID  = "";
 orderID  = ib.PlaceOrder(sTicker, "SELL", pContracts, "MKT", 0, 0, "GTC", True, tickMult, "outsideRTH");
 if(orderID  != "")
 {
  ordType = "ManSell";
  newState = ordManSell; 
  StaticVarSet(VarPfx + "TargetPositions", positions - pContracts);
  StaticVarSetText(VarPfx + "ordID", orderID);
  StaticVarSet(VarPfx + "GetStatus", True);
  StaticVarSet(VarPfx + "WaitForConfirm",  True); 
  if(DebugOn)  _TRACE("#, ManSel1, " + ordType + ", Time=" + fFormatTime(sysTimeStr) + ", OrderID=" + orderID + 
   ", OrderState=" + fCvtState(newState) + ", Close=" + NumToStr(LastValue(Close), 1.2));    
 }
 return newState; // return the type of order that was made
}

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ######################################    CANCEL     CANCEL     CANCEL     CANCEL     CANCEL     CANCEL    ######################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################
 
function fCancelPositions(ib, oState, OID, positions)  // we are neither long or short
// trigger - trg defines the type of order
{
 newState = oState; 
 // this if statement prevents making multiple orders - subsequent orders are ignored
 if( oState == ordSell OR oState == ordShort)
 {
  if(OID != "") // used to cancel a sell order that has not been filled  
  {
   newState = ordCancelSell;
   ordType = "CancelSell";
   ib.CancelOrder(OID); 
   StaticVarSet(VarPfx + "GetStatus", True);
   if(DebugOn)  _TRACE("#, Cancel 1, " + ordType + ", Time=" + fFormatTime(sysTimeStr) + ", OrderState =" + fCvtState(newState) + 
    ", OrderID=" + OID);    
  }
 }
 else if(oState == ordBuy OR oState == ordCover)
 {
  if(OID != "") // used to cancel a buy order that has not been filled
  {
   newState = ordCancelBuy;
   ordType = "CancelBuy";
   ib.CancelOrder(OID); 
   StaticVarSet(VarPfx + "GetStatus", True);
   if(DebugOn)  _TRACE("#, Cancel 2, " + ordType + ", Time=" + fFormatTime(sysTimeStr) + ", OrderState=" + fCvtState(newState) + 
    ", OrderID=" + OID);    
  }
 }
 return newState; // return the type of order that was made
}

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ######################################      BUY      BUY      BUY      BUY      BUY      BUY      BUY      ###################################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################
 
function fBuyPositions(ib, oState, OID, positions)  // we are neither long or short
// trigger - trg defines the type of order
{
 newState = oState; 
 price = LastC;
 if(DebugOn)  _TRACE("#, Buy, OrderType= " + OrderType + ", " + NumToStr(OrderType == "MKT", 1)); 
 // this if statement prevents making multiple orders - subsequent orders are ignored
  if( oState == ordNone AND OID == "") // program trade and no open positions or pending order sent
 {
  orderID = "";
  if(OrderType == "MKT") orderID = ib.PlaceOrder(sTicker, "BUY",  pContracts, "MKT", 0, 0, "GTC", True, tickMult, "outsideRTH");
  else if(OrderType == "STP") orderID = ib.PlaceOrder(sTicker, "BUY",  pContracts, "STP", 0, price, "GTC", True, tickMult, "outsideRTH");
  else if(OrderType == "LMT") orderID = ib.PlaceOrder(sTicker, "BUY",  pContracts, "LMT", price, 0, "GTC", True, tickMult, "outsideRTH");
  if(DebugOn)  _TRACE("#, Buy, OrderType= " + OrderType + ", OID=" + ORderID ); 
  if(orderID != "")
  {
   ordType = "ProgBuy";
   newState = ordBuy;
   StaticVarSetText(VarPfx + "ordID", orderID);
   StaticVarSet(VarPfx + "GetStatus", True);
   StaticVarSet(VarPfx + "WaitForConfirm",  True); 
   if(DebugOn)  _TRACE("#, Buy, " + ordType + ", Time" + fFormatTime(sysTimeStr) + ", OrderState=" + fCvtState(newState) +  
    ", OrderID=" + orderID  +  ", Price=" + NumToStr(LastC, 1.2));  
  }
 }
 return newState; // return the type of order that was made
}
      
// ##############################################################################################################################################################
// ##############################################################################################################################################################
// #################################    SHORT     SHORT     SHORT     SHORT     SHORT    ########################################################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################

function fShortPositions(ib, oState, OID, positions) // we are neither long or short
{
 newState = oState; 
 price = LastC;
 if(DebugOn)  _TRACE("#, Short, OrderType= " + OrderType + ", OID=" + OID + ", " + NumToStr(OrderType == "MKT", 1));  
 if( oState == ordNone AND OID == "")   // no sell order sent and no position and no current order
 {
  orderID = "";
  if(OrderType == "MKT") orderID = ib.PlaceOrder(sTicker, "SELL", pContracts, "MKT", 0, 0, "GTC", True, tickMult, "outsideRTH");
  else if(OrderType == "STP") orderID = ib.PlaceOrder(sTicker, "SELL", pContracts, "STP", 0, price, "GTC", True, tickMult, "outsideRTH");
  else if(OrderType == "LMT") orderID = ib.PlaceOrder(sTicker, "SELL", pContracts, "LMT", price, 0, "GTC", True, tickMult, "outsideRTH");
  if(DebugOn)  _TRACE("#, Short, OrderType= " + OrderType + ", OID=" + ORderID ); 
  if(orderID != "")
  {
   ordType = "ProgShort";
   newState = ordShort;
   StaticVarSetText(VarPfx + "ordID", orderID);
   StaticVarSet(VarPfx + "GetStatus", True);
   StaticVarSet(VarPfx + "WaitForConfirm",  True); 
   if(DebugOn)  _TRACE("#, Short, " + ordType + ", Time=" + fFormatTime(sysTimeStr) + ", OrderState=" + fCvtState(newState) + 
    ", OrderID=" + orderID + ", Price=" + NumToStr(price, 1.2));    
  }
 }
 return newState; // return the type of order that was made
}

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// #################################    SELL     SELL     SELL     SELL     SELL      SELL     SELL     #########################################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################

function fSellPositions(ib, oState, OID, positions) // we are neither long or short
{
 newState = oState; 
 if( oState == ordNone ) // close a long position
 {
  // exit the current position with a market order
  orderID = "";
  orderID = ib.PlaceOrder(sTicker, "SELL", abs(positions), "MKT", 0, 0, "GTC", True, tickMult, "outsideRTH");
  ordType = "ProgSell";
  newState = ordSell;
  StaticVarSetText(VarPfx + "ordID", orderID);
  StaticVarSet(VarPfx + "GetStatus", True);
  StaticVarSet(VarPfx + "WaitForConfirm",  True); 
  if(DebugOn)  _TRACE("#, Sell, " + ordType + ", Time=" + fFormatTime(sysTimeStr) + ", OrderState=" + fCvtState(newState) +  
   ", OrderID=" + orderID +  ", Close=" + NumToStr(LastValue(Close), 1.2));    
 }
 return newState; // return the type of order that was made
}

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ################################    COVER      COVER      COVER      COVER      COVER      COVER      COVER     ##############################################
// ##############################################################################################################################################################
// ##############################################################################################################################################################

function fCoverPositions(ib, oState, OID, positions)  // we are neither long or short
{
 newState = oState; 
 if( oState == ordNone ) // program cover and go flat
 {
  orderID = "";
  orderID = ib.PlaceOrder(sTicker, "BUY", abs(positions), "MKT", 0, 0, "GTC", True, tickMult, "outsideRTH");
  ordType = "progCover";
  newState = ordCover;
  StaticVarSetText(VarPfx + "ordID", orderID); 
  StaticVarSet(VarPfx + "GetStatus", True);
  StaticVarSet(VarPfx + "WaitForConfirm",  True); 
  if(DebugOn)  _TRACE("#, Cover, " + ordType + ", Time=" + fFormatTime(sysTimeStr) + ", OrderState=" + fCvtState(newState) +  
   ", OrderID=" + orderID +  ", Close=" + NumToStr(LastValue(Close), 1.2));    
 }
 return newState; // return the type of order that was made
}
 

// ##############################################################################################################################################################
// ##############################################################################################################################################################
// ############  Order Precessing Loop  Order Precessing Loop  Order Precessing Loop  Order Precessing Loop  Order Precessing Loop   #######################
// ##############################################################################################################################################################
// ##############################################################################################################################################################

if( StaticVarGet(VarPfx + "AutoTrading") == True AND // auto trading parameter is set on
 IntervalOK AND   // chart is the same interval as the Chart period selected 
 sTicker == Name() )  // the chart symbol is the same as the ticker parameter
{
 ibc = GetTradingInterface("IB");
 if(ibc)
 {
  ConnectedStatus = ibc.IsConnected(); // get the connection status, 2 is OK

  // the foloowing code closes trades at the end of the day.
  // it does this in steps. 1) cancels all open orders. 2) Closes all positions. 3) resets the control var EOD
  EodVar = StaticVarGetText(VarPfx + "EOD"); 
  if(sysTime == closeTime + 1 AND EodVar == "") // this is the close time parameter + 1 seconds 
  {
   ibc.CancelAllPendingOrders(sTicker); 
   StaticVarSetText(VarPfx + "EOD", "Cancel");
   _TRACE("#, #####  CancelAll end of day  #####");   
  }

  if(sysTime == closeTime + 5 AND EodVar == "Cancel") // this is the close time parameter + 5 seconds 
  {
   ibc.CloseAllOpenPositions(sTicker);
   StaticVarSetText(VarPfx + "EOD", "Close");
   _TRACE("#, #####  CloseAll end of day  #####");   
  }

  if(sysTime == closeTime + 8 AND EodVar == "Close") // this is the close time parameter + 8 seconds 
  {
   ibc.CloseAllOpenPositions(sTicker);
   StaticVarSetText(VarPfx + "EOD", "");
   _TRACE("#, *****  Reset EOD static var  *****");   
  }
  // end of close trades at ene of day

  // this is where the trade processing is done
  if( sysTime < closeTime AND (ConnectedStatus == 2 OR ConnectedStatus == 3) ) // connected to TWS with no error messages
  {
   if(StaticVarGet(VarPfx + "SystemInitialized") ==  True)
   {
    StaticVarSet(VarPfx + "SystemInitialized", False);  
    ibc.CancelAllPendingOrders(); // cancel any open orders on start or reset
   }

   // retrieve static variables
   numPositions  = ibc.GetPositionSize(sTicker); 
   StaticVarSet(VarPfx + "numPositions", numPositions);

   if(DebugOn)  _TRACE("#, SysLoop 0, Positions=" + NumToStr(StaticVarGet(VarPfx + "numPositions"), 1.0) + 
    ", GetStatus=" + NumToStr(GetStatus, 1.0) + ", OrderState=" + fCvtState(OrderState) + ", OrderID=" + ordID + 
    ", WaitForConfirm=" + NumToStr(WaitForConfirm, 1.0) + "\n" ); 

   // GetStaus = false indicates TWS has completed processing the order
   // Wait for the trade to be confirmed by a change in the number of positions before resetting the order state and waitforconfirm flag
   // this is used to prevent placing an order if the signal is still active after a filled status from TWS
   if(WaitForConfirm AND !GetStatus)
   {
    if(DebugOn)  _TRACE("#, WaitForConfirm, OrderState = " + fCvtState(OrderState) + "\n"); 
    // note: WaitForConfirm set false if order cancelled, see GetStatus Cancelled logic
    if( (OrderState == OrdBuy  AND numPositions > 0)  OR 
     (OrderState == OrdShort AND numPositions < 0)  OR
     (OrderState == OrdCover AND numPositions == 0)  OR 
     (OrderState == OrdSell  AND numPositions == 0)  )
    {  
     if(DebugOn)  _TRACE("#, Program trade WaitForConfirm complete"); 
     OrderState = ordNone; StaticVarSet(VarPfx + "OrderState", OrderState);
     WaitForConfirm = False; StaticVarSet(VarPfx + "WaitForConfirm",  False); 
    }
    // user made a manual order so wait for the number of positions to indicate the purchase before resetting order state and waitforconfirm flags
    else if(OrderState == ordManBuy OR OrderState == ordManSell)
    {
     if(DebugOn)  _TRACE("#, Manual trade processed, target positions=" + NumToStr(StaticVarGet(VarPfx + "TargetPositions"), 1.0)); 
     if( numPositions  == StaticVarGet(VarPfx + "TargetPositions")) 
     {
      OrderState = ordNone; StaticVarSet(VarPfx + "OrderState", OrderState);
      StaticVarSet(VarPfx + "WaitForConfirm",  False); 
      StaticVarSet(VarPfx + "TargetPositions", 0);
     }
    }
    // user requested close all positions so wait for the number of positions to indicate all positions are closed before resetting 
    // order state AND waitforconfirm flags
    else if(OrderState == ordCloseAll ) 
    {
     if(numPositions  == 0) 
     {
      if(DebugOn)  _TRACE("#, Close all processed"); 
      OrderState  = ordNone;  StaticVarSet(VarPfx + "OrderState", OrderState);
      ordID = ""; StaticVarSetText(VarPfx + "ordID", "");
      StaticVarSet(VarPfx + "GetStatus", False); 
      StaticVarSet(VarPfx + "WaitForConfirm",  False); 
     }
    } // end close all
   }
  
   // ##############################################################################################################################################################
   // ###################    Trigger Control    Trigger Control    Trigger Control    Trigger Control    Trigger Control    Trigger Control   ######################
   // ###################    This section takes the indicator timing and converts it to one shot triggers required for orders.                ######################
   // ##############################################################################################################################################################

   // waitforconfirm and getstatus flags are used to prevent multiple orders while a current order is being processed
   // orders are onluy allowed if the waitforconfirm and getstatus flags are false

   BuyTrigger = SellTrigger = ShortTrigger = CoverTrigger = False;
   if(DebugOn)  _TRACE("#, AllowInd 0, Indicator, Buy=" + NumToStr(BuyInd, 1.0) + ", Sell=" + NumToStr(SellInd, 1.0) + 
    ", Short=" + NumToStr(ShortInd, 1.0) + ", Cover=" + NumToStr(CoverInd, 1.0));
   if(!WaitForConfirm AND !GetStatus  ) // allow indicators to pass unless a trade to being processed
   {
    // This is sequence sensitive. cover and sell should close positions before new positions are taken.
    // **********  CAUTION *****************
    // but note that if your system does not generate the sell and cover signals the order process can hang and not allow trades
    // Pause parameter blocks all programmed trading 
    if( numPositions > 0 AND SellInd AND !Pause) // sell is only allowed when there are a positive number of positions
    {
     SellTrigger = True; 
     if(DebugOn)  _TRACE("#, AllowInd 1 Sell trigger"); 
    }
    else if( numPositions < 0 AND CoverInd AND !Pause) // cover is only allowed when there are a negative number of positions
    {
     CoverTrigger = True;  
     if(DebugOn)  _TRACE("#, AllowInd 2 Cover trigger"); 
    }
    else if( !Pause AND numPositions == 0 ) // buy and short is only allowed when there are no positions
    {
     if(BuyInd ) 
     {
      BuyTrigger = True; 
      if(DebugOn)  _TRACE("#, AllowInd 3, Buy trigger"); 
     }
     else if(ShortInd ) 
     {
      ShortTrigger = True; 
      if(DebugOn)  _TRACE("#, AllowInd 4, Short trigger"); 
     }
    }
   } // end allowIndicators 

   // signal reversal and we have open an order and the trend changes direction
   else if ( WaitForConfirm AND numPositions == 0) // Reversal signal with an open order
   {
    if(DebugOn)  _TRACE("#, Reversal Cancel 0");
    if( (OrderState == ordBuy OR OrderState == ordCover ) AND SellInd) 
    {
     SellTrigger   = True; 
     OrderState == OrdNone;  StaticVarSet(VarPfx + "OrderState",  OrdNone); 
     WaitForConfirm = False; StaticVarSet(VarPfx + "WaitForConfirm",  False); 
     if(DebugOn)  _TRACE("#, Reversal Cancel 1, SellTrigger=" + NumToStr(SellTrigger, 1.0));
    }
    else if( (OrderState == ordShort OR OrderState == ordSell ) AND CoverInd ) 
    {
     CoverTrigger  = True; 
     OrderState == OrdNone;  StaticVarSet(VarPfx + "OrderState",  OrdNone); 
     WaitForConfirm = False; StaticVarSet(VarPfx + "WaitForConfirm",  False); 
      if(DebugOn)  _TRACE("#, Reversal Cancel 2, CoverTrigger=" + NumToStr(CoverTrigger, 1.0));
    }
   }
   if(DebugOn)  _TRACE("#, AllowInd End, Buy=" + NumToStr(BuyTrigger, 1.0) + ", Sell=" + NumToStr(SellTrigger, 1.0) + 
     ", Short=" + NumToStr(ShortTrigger, 1.0) + ", Cover=" + NumToStr(CoverTrigger, 1.0));

   // #################################################################################################################################################
   // ########    Stateless processes      Stateless processes      Stateless processes      Stateless processes    Stateless processes    ############
   // #################################################################################################################################################
   if(CancelAll)
   {
    ibc.CancelAllPendingOrders(sTicker); 
    OrderState = ordNone; StaticVarSet(VarPfx + "OrderState", OrderState);
    ordType = "CancelAll";
    StaticVarSet(VarPfx + "WaitForConfirm",  False); 
    StaticVarSet(VarPfx + "GetStatus",  False); 
    if(DebugOn)  _TRACE("#, Trigger CancelAll, OrderState=" + fCvtState(OrderState) + ", OrderID=" + ordID); 
    ordID = ""; StaticVarSetText(VarPfx + "ordID", "");
   }
   else if(CloseAll )
   {
    // close all positions
    ibc.CancelAllPendingOrders(sTicker); 
    ibc.CloseAllOpenPositions(sTicker);
    OrderState = ordCloseAll; StaticVarSet(VarPfx + "OrderState", OrderState );
    ordType = "CloseAll";
    StaticVarSet(VarPfx + "GetStatus",  True); 
    StaticVarSet(VarPfx + "WaitForConfirm",  True); 
    if(DebugOn)  _TRACE("#, *****  Trigger CloseAll " + ordID + ", OrderState=" + fCvtState(OrderState) + 
     ", SysTime =" + NumToStr(SysTime, 1.0, False) + "  ****"); 
   }
   else if(!GetStatus AND ManualBuy) // manual  buy the number of contracts defined in pContracts   
   { 
    state = fManBuyPositions(ibc, OrderState, ordID, numPositions);  
    StaticVarSet(VarPfx + "OrderState", state); 
   }
   else if(!GetStatus AND ManualSell) // manual sell number of contracts defined in pContracts
   { 
    state = fManSellPositions(ibc, OrderState, ordID, numPositions);  
    StaticVarSet(VarPfx + "OrderState", state); 
   }

   // #################################################################################################################################################
   // #################################################################################################################################################
   // ##########      Program Trading         Program Trading       Program Trading        Program Trading       Program Trading      #################
   // ##########      Note that the order is sequence sensitive as sell and cover should be processed before buy and short.      #################
   // #################################################################################################################################################
   // #################################################################################################################################################
   else if(!WaitForConfirm ) // not waiting for a trade to settle
   {
    if( SellTrigger AND numPositions > 0) // sell to go flat
    {
     state = fSellPositions(ibc, OrderState, ordID, numPositions);  
     OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
     if(DebugOn)  _TRACE("#, Trigger ordSell, OrderState=" + fCvtState(state)); 
    }
    else if( CoverTrigger AND numPositions < 0) // buy to go flat
    {
     state = fCoverPositions(ibc, OrderState, ordID, numPositions);  
     OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
     if(DebugOn)  _TRACE("#, Trigger ordCover, OrderState=" + fCvtState(state)); 
    }
    else if( BuyTrigger )
    {
     state = OrderState;
     if(numPositions == 0) // buy n contracts
      state = fBuyPositions(ibc, OrderState, ordID, numPositions);  
     else if(numPositions < 0) // close short position first then go long after filled 
      state = fCoverPositions(ibc, OrderState, ordID, numPositions); 
     OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
     if(DebugOn)  _TRACE("#, Trigger ordBuy, OrderState=" + fCvtState(state)); 
    }
    else if( ShortTrigger )
    {
     state = OrderState;
     if(numPositions == 0) // sell n contracts
      state = fShortPositions(ibc, OrderState, ordID, numPositions);  
     else if(numPositions > 0) // close long first then go short after filled
      state = fSellPositions(ibc, OrderState, ordID, numPositions);  
     OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
     if(DebugOn)  _TRACE("#, Trigger ordShort, OrderState=" + fCvtState(state)); 
    }
   }

   // #################################################################################################################################################
   // #################################################################################################################################################
   // ##########      Order Status Processing     Order Status Processing     Order Status Processing     Order Status Processing     #################
   // #################################################################################################################################################
   // ###  order states  ordNone = 20; ordCancelBuy = 21; ordCancelSell = 22; ordSell = 23; ordBuy = 24; ordCover = 25; ordShort = 26; 
   // ###       ordCancelAll = 27; ordCloseAll = 28; ordManBuy = 29; ordManSell = 30;
   // #################################################################################################################################################
   // #################################################################################################################################################
   ordID = StaticVarGet(VarPfx + "ordID");
   if(DebugOn)  _TRACE("#, OrdState 0, GetStatus=" + NumToStr(GetStatus, 1.0) + ", Positions=" + NumToStr(numPositions, 1.0) + 
    ", OrderState=" + fCvtState(OrderState) + ", OrderID=" + ordID + ", Time=" + fFormatTime(sysTimeStr)); 
   // process the status messages after an order has been sent or cancelled
   tempStatus = "None";
   if(GetStatus)
   {
    tempStatus = ibc.GetStatus( ordID, True );  // get order status 
    if(tempStatus == "Filled")
    {
     // make sure the numPositions is true for the operation being conducted
     // this prevents another order as soon as this one is filled
     StaticVarSet(VarPfx + "GetStatus", False); 
     if( OrderState == ordCancelSell OR OrderState == ordCancelBuy )
     {
      OrderState = ordNone; 
      StaticVarSet(VarPfx + "OrderState", OrderState ); 
     } 
     if(DebugOn)  _TRACE("#, OrdState 1 Filled, OrderState=" + fCvtState(OrderState) + ", OrderID=" + ordID);
     ordID = ""; StaticVarSetText(VarPfx + "ordID", "");
    } // end filled
    else if(tempStatus == "PreSubmitted"  OR 
       tempStatus == "PendingSubmit" OR 
       tempStatus == "Pending"   OR 
       tempStatus == "ApiPending"  OR 
       tempStatus == "Submitted"  )
    {
     if( numPositions != 0 AND (OrderState == ordCancelSell OR OrderState == ordCancelBuy ))
     {
      OrderState = ordNone; 
      StaticVarSet(VarPfx + "OrderState", OrderState ); 
      StaticVarSet(VarPfx + "GetStatus", False); 
     } 
     if(CoverTrigger AND (OrderState == ordShort OR OrderState == ordSell))
     {
      // call Cancel to cancel the sell order and set up to reverse
      state = fCancelPositions(ibc, OrderState, ordID, numPositions);  
      OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
      if(DebugOn)  _TRACE("#, OrdState 2a, CancelSell, OrderState=" + fCvtState(state)); 
     }
     else if(SellTrigger AND (OrderState == ordBuy OR OrderState == ordCover))
     {
      // call Cancel to cancel the buy order and set up to reverse
      state = fCancelPositions(ibc, OrderState, ordID, numPositions);  
      OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
      if(DebugOn)  _TRACE("#, OrdState 2c, CancelBuy , OrderState=" + fCvtState(state)); 
     }
    } // end status preSubmitted or Pending
    else if(tempStatus == "Cancelled")
    { 
     StaticVarSet(VarPfx + "GetStatus", False); 
     StaticVarSet(VarPfx + "WaitForConfirm",  False); 
     OrderState = ordNone;   StaticVarSet(VarPfx + "OrderState", ordNone);
     if(DebugOn)  _TRACE("#, OrdState 3 Cancel, OrderState=" + fCvtState(OrderState) + 
       ", OrderID=" + ordID + ", Positions=" + NumToStr(numPositions , 1.0) + "\n"); 
      ordID = ""; StaticVarSetText(VarPfx + "ordID", "");  
    } 
    else if(tempStatus == "Error")
    {
     msg = ibc.GetLastError(0); 
     error = fErrorProcessor(msg); 
     if(DebugOn)  _TRACE("#, OrdState 4, Error code=" + error );   
     StaticVarSet(VarPfx + "SetErrorState", True);  
     // NOTE: For error not listed below look at the message notes at the end of the program to see how or if they were handled.
     if(error == "135" OR error == "2106" OR error == "2109") // out of normal trading hours
     {
      StaticVarSet(VarPfx + "GetStatus", False); 
      OrderState = ordNone;   StaticVarSet(VarPfx + "OrderState", ordNone);
       ordID = ""; StaticVarSetText(VarPfx + "ordID", "");  
     }
     else if(error == "201")
     {
      if(OrderState == ordShort OR OrderState == ordSell)
      {
       // call Cancel to cancel the sell order and set up to reverse
       state = fCancelPositions(ibc, OrderState, ordID, numPositions);  
       OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
      }
      else if(OrderState == ordBuy OR OrderState == ordCover)
      {
       // call Cancel to cancel the buy order and set up to reverse
       state = fCancelPositions(ibc, OrderState, ordID, numPositions);  
       OrderState = state; StaticVarSet(VarPfx + "OrderState", state); 
      }
     }
     else 
     { 
      if(DebugOn)  _TRACE("#, OrdState 10 Unexpected status=" + tempstatus + ", OrderState=" + fCvtState(OrderState) + 
       ", OrderID=" + ordID); 
     }
    } // end status error
    else 
    { 
     if(DebugOn)  _TRACE("#, OrdState 11 Unexpected status=" + tempstatus + ", OrderState=" + fCvtState(OrderState) + 
      ", OrderID=" + ordID); 
    }
   } // end get status  

   if( StaticVarGet(VarPfx + "SetErrorState") == True) 
   {
    errorMsg = ibc.GetLastError(ordID);  
    if(errorMsg == "None" OR errorMsg == "")
     StaticVarSet(VarPfx + "SetErrorState", False); 
    else
    {
     SetChartBkColor( colorTan); 
     VisibleBars = Status( "LastVisibleBar" ) - Status( "FirstVisibleBar" ); 
     instructions = "\n  Determine what the error is. Use trace if necessary.\n  Cancel or close all orders on TWS.\n  Press Reset to continue.";  
     PlotText( "Error " + errorMsg + instructions, BarCount - VisibleBars / 2, 
      LastValue( ( HHV(H, VisibleBars) + LLV(L, VisibleBars)) / 2), colorWhite, colorBlack);
     if(DebugOn)  _TRACE("#, Unexpected error msg=" + errorMsg + ", OrderState=" + fCvtState(OrderState) + ", OrdID=" + OrdID);
    } 
   }
  
   else if (Pause )
   {
    SetChartBkColor( colorLightGrey); 
    VisibleBars = Status( "LastVisibleBar" ) - Status( "FirstVisibleBar" ); 
    PlotText( "######\nTrading\nPaused\n######", BarCount - VisibleBars / 2, 
     LastValue( ( HHV(H, VisibleBars) + LLV(L, VisibleBars)) / 2), colorWhite, colorBlack);
   }
   if(ConnectedStatus == 2) stat = "Connected."; else if(ConnectedStatus == 3) stat = "Connected with warnings.";
   if(StaticVarGet(VarPfx + "ConnectOK") == False) 
    StaticVarSet(VarPfx + "ConnectOK", True); 
   printf("\nStatus:" + 
    "\n  Symbol = " + sTicker + 
    "\n  TWS " + stat + 
    "\n  Last TWS message = " + errorMsg + 
    "\n  Order ID = " + WriteIf(ordID != "", OrdId, "None") + 
    "\n  OrderState = " + fCvtState(OrderState) + 
    "\n  Order status = " + tempStatus +
    "\n  Positions = " + NumToStr(Nz(numPositions), 1.0, False) );
  } // end is connected
  else if( ConnectedStatus == 0 OR ConnectedStatus == 1) // lost connection
  {
   // handle commection errors 
   if(ConnectedStatus == 0) stat = "Not Connected."; else if(ConnectedStatus == 1) stat = "Lost Connection.";
   SetChartBkColor( colorYellow);  
   VisibleBars = Status( "LastVisibleBar" ) - Status( "FirstVisibleBar" ); 
   PlotText( "TWS not connected. Some reasons are:\nTWS error message: " + errorMsg + "\nIncoming connection has not been accepted.", BarCount - VisibleBars / 2, LastValue(HHV(H, VisibleBars)), colorWhite, colorBlack);
   printf("\nTWS Status: " + stat + "\n"); 
  } // end connection error  
  else if (sysTime > closeTime)
  {
   VisibleBars = Status( "LastVisibleBar" ) - Status( "FirstVisibleBar" ); 
   PlotText( "###########\nMarket closed\n###########", BarCount - VisibleBars / 2, LastValue(HHV(H, VisibleBars)), colorWhite, colorBlack);
  }
 } // end if ibc
} // end order processing loop

 // #################################################################################################################################################
 // #################################################################################################################################################
 // ##########      Commentary  Commentary  Commentary  Commentary  Commentary  Commentary  Commentary  Commentary   ################
 // #################################################################################################################################################
 // #################################################################################################################################################

else // autotrade is off due to an error or trading is turned off
{
 // if error state, display state in title bar
 // feedback key info into title bar
 SetChartBkColor( colorPink);
 text = "\nStatus: \nAutoTrading is off. Some of the reasons are:\n" +
 " 1. Autotrading is turned off\n" +
 " 2. TWS has not been started or isn't functioning.\n" + 
 " 3. Set chart to " + sTicker + ".\n" + 
 " 4. Chart period mismatch.\n"; // end text

 printf(text);
 VisibleBars = Status( "LastVisibleBar" ) - Status( "FirstVisibleBar" ); 
 PlotText(text, BarCount - VisibleBars / 2, LastValue(HHV(H, VisibleBars)), colorWhite, colorBlack);

}
_SECTION_END(); 

// #################################################################################################################################################
// #################################################################################################################################################
// ##########       Setup and WARNINGS      Setup and WARNINGS      Setup and WARNINGS      Setup and WARNINGS         ##############
// #################################################################################################################################################
// #################################################################################################################################################

// Before Auto trading will trade orders and have them filled automatically you must register your copy of IB Controller. See File>Enter unlock code.
// if it is NOT registered the order will be sent but a T will appear on TWS and the order will not be transmitted to the market. 
// Once IBC is registered AND the code is entered orders will be processed automatically.

// This release level requires TWS 888.3 or above, IB.DLL of 1.8.2 or above, and BrokerIB.exe ( IB Controller) of 1.2.1 or above.
// These are required to handle after hours trading and back filling. This program will not work correctly unless these releases are installed.
// TWS may also require an update to JAVA. Check their site for recommendations.
Previous Post Next Post