function CreateTradeTrackingObject(){ // Comma separated list. var PL = { bShortStopHit: false, bBuyStopHit: false, bOkToTrade: false, bAmShort: false, bCoverShort: false, bAmLong: false, bSellLong: false, bAlertsOn: false, bInit: false, bBackTestOn: false, bPrintHeader: true, bPrintTrades: true, bDrawArrows: true, sProgramName: null, nBuyP: null, nSellP: null, nShortP: null, nCoverP: null, nPL: 0, nSumPL: 0, nSumP: 0, nSumL: 0, nSumLongPL: 0, nSumShortPL: 0, nNumOfW: 0, nNumOfL: 0, nNumOfZ: 0, nAveP: 0, nAveL: 0, nNumLong: 0, nNumShort: 0, nSellStop: 0, nBuyStop: 0, nNumOfLongTrades: 0, nNumOfShortTrades: 0, nStopLossTrades: 0, nTradesArrayIndex: 0, aTradesArray: [] } return PL; } function CoverShort(Obj, nPriceCS, bBuyStopHit, bPlayAlert){ if(Obj.nShortP == null) return; var dBarDateTime = getValue("month", 0) + "/" + getValue("day", 0) + " " + getValue("time", 0).ToShortTime(); DoAlerts(Obj.bAlertsOn, bPlayAlert, Obj.sProgramName, "train.wav"); Obj.bAmShort = false; Obj.bOkToTrade = false; Obj.nCoverP = nPriceCS; Obj.nPL = Obj.nShortP - Obj.nCoverP; Obj.nSumPL += Obj.nPL; Obj.nSumShortPL += Obj.nPL; if(bBuyStopHit){ Obj.nStopLossTrades++; Obj.bBuyStopHit = false; Obj.bOkToTrade = false; } if(Obj.bDrawArrows) drawTextRelative(0, BottomRow2, "\u00E9", Color.yellow, null, Text.PRESET|Text.CENTER, "Wingdings", 10, "ShortCovered"+rawtime(0)); if(Obj.nPL > 0){ Obj.nSumP += Obj.nPL; Obj.nNumOfW++; Obj.nAveP = Obj.nSumP / Obj.nNumOfW; if(Obj.bPrintTrades){ PrintTradeValues(Obj.nStopLossTrades, Obj.nNumOfShortTrades, "-----", "-----", Obj.nAveP, "-----", Obj.nNumOfW, Obj.nNumOfZ, "-----", Obj.nSumP, Obj.nSumShortPL,"-----", Obj.nSumPL, Obj.nPL, Obj.nShortP, Obj.nCoverP, dBarDateTime); if(isLastBarOnChart()) PrintHeader(Obj.sProgramName); } }else if(Obj.nPL < 0){ Obj.nSumL += Obj.nPL; Obj.nNumOfL++; Obj.nAveL = Obj.nSumL / Obj.nNumOfL; if(Obj.bPrintTrades){ PrintTradeValues(Obj.nStopLossTrades, Obj.nNumOfShortTrades, "-----", Obj.nAveL, "-----", Obj.nNumOfL, "-----", Obj.nNumOfZ, Obj.nSumL, "-----", Obj.nSumShortPL, "-----", Obj.nSumPL, Obj.nPL, Obj.nShortP, Obj.nCoverP, dBarDateTime); if(isLastBarOnChart()) PrintHeader(Obj.sProgramName); } }else{ Obj.nNumOfZ++; if(Obj.bPrintTrades){ PrintTradeValues(Obj.nStopLossTrades, Obj.nNumOfShortTrades, "-----", "-----", "-----", "-----", "-----", Obj.nNumOfZ, "-----", "-----", Obj.nSumShortPL,"-----", Obj.nSumPL, Obj.nPL, Obj.nShortP, Obj.nCoverP, dBarDateTime); if(isLastBarOnChart()) PrintHeader(Obj.sProgramName); } } Obj.nShortP = null; if(Obj.bBackTestOn && Strategy.isInTrade() == true){ Strategy.doCover("CoverShort", Strategy.LIMIT, Strategy.THISBAR, 1, Obj.nCoverP); } } function SellLong(Obj, nPriceSL, bSellStopHit, bPlayAlert){ if(Obj.nBuyP == null) return; var dBarDateTime = getValue("month", 0) + "/" + getValue("day", 0) + " " + getValue("time", 0).ToShortTime(); DoAlerts(Obj.bAlertsOn, bPlayAlert, Obj.sProgramName, "train.wav"); Obj.bAmLong = false; Obj.bOkToTrade = false; Obj.nSellP = nPriceSL; Obj.nPL = Obj.nSellP - Obj.nBuyP; Obj.nSumPL += Obj.nPL; Obj.nSumLongPL += Obj.nPL; if(bSellStopHit){ Obj.nStopLossTrades++; Obj.bSellStopHit = false; Obj.bOkToTrade = false; } if(Obj.bDrawArrows) drawTextRelative(0, BottomRow1, "\u00EA", Color.white, null, Text.PRESET|Text.CENTER, "Wingdings", 10, "LongSold"+rawtime(0)); if(Obj.nPL > 0){ Obj.nSumP += Obj.nPL; Obj.nNumOfW++; Obj.nAveP = Obj.nSumP / Obj.nNumOfW; if(Obj.bPrintTrades){ PrintTradeValues(Obj.nStopLossTrades, "-----", Obj.nNumOfLongTrades, "-----", Obj.nAveP, "-----", Obj.nNumOfW, Obj.nNumOfZ, "-----", Obj.nSumP, "-----", Obj.nSumLongPL, Obj.nSumPL, Obj.nPL, Obj.nSellP, Obj.nBuyP, dBarDateTime); if(isLastBarOnChart()) PrintHeader(Obj.sProgramName); } }else if(Obj.nPL < 0){ Obj.nSumL += Obj.nPL; Obj.nNumOfL++; Obj.nAveL = Obj.nSumL / Obj.nNumOfL; if(Obj.bPrintTrades){ PrintTradeValues(Obj.nStopLossTrades, "-----", Obj.nNumOfLongTrades, Obj.nAveL, "-----", Obj.nNumOfL, "-----", Obj.nNumOfZ, Obj.nSumL, "-----", "-----", Obj.nSumLongPL, Obj.nSumPL, Obj.nPL, Obj.nSellP, Obj.nBuyP, dBarDateTime); if(isLastBarOnChart()) PrintHeader(Obj.sProgramName); } }else{ Obj.nNumOfZ++; if(Obj.bPrintTrades){ PrintTradeValues(Obj.nStopLossTrades, "-----", Obj.nNumOfLongTrades, "-----", "-----", "-----", "-----", Obj.nNumOfZ, "-----", "-----", "-----", Obj.nSumLongPL, Obj.nSumPL, Obj.nPL, Obj.nSellP, Obj.nBuyP, dBarDateTime); if(isLastBarOnChart()) PrintHeader(Obj.sProgramName); } } Obj.nBuyP = null; if(Obj.bBackTestOn && Strategy.isInTrade() == true){ Strategy.doSell("CloseLong", Strategy.LIMIT, Strategy.THISBAR, 1, Obj.nSellP); } } function GoShortLimit(Obj, nPriceGS, bPlayAlert){ DoAlerts(Obj.bAlertsOn, bPlayAlert, Obj.sProgramName, "phone.wav"); Obj.bOkToTrade = false; Obj.nShortP = nPriceGS; Obj.bAmShort = true; Obj.nNumShort++; Obj.nNumOfShortTrades++; if(Obj.bBackTestOn) Strategy.doShort("OpenShort", Strategy.LIMIT, Strategy.THISBAR, 1, Obj.nShortP); Obj.nBuyStop = highest(10, high(),0); if(Obj.bDrawArrows) drawTextRelative(0, BottomRow2, "\u00EA", Color.red, null, Text.PRESET|Text.CENTER, "Wingdings", 10, "GoShort"+rawtime(0)); } function GoLongLimit(Obj, nPriceGL, bPlayAlert){ DoAlerts(Obj.bAlertsOn, bPlayAlert, Obj.sProgramName, "phone.wav"); Obj.bOkToTrade = false; Obj.nBuyP = nPriceGL; Obj.bAmLong = true Obj.nNumLong++; Obj.nNumOfLongTrades++; if(Obj.bBackTestOn) Strategy.doLong("OpenLong", Strategy.LIMIT, Strategy.THISBAR, 1, Obj.nBuyP); Obj.nSellStop = lowest(10, low(),0); if(Obj.bDrawArrows) drawTextRelative(0, BottomRow1, "\u00E9", Color.green, null, Text.PRESET|Text.CENTER, "Wingdings", 10, "GoLong"+rawtime(0)); } function PrintHeader(sProgram_Name){ PrintValues("StopLossTrades", "TotalST", "TotalLT", "nAveL", "nAveP", "nNumOfL", "nNumOfW", "nNumOfZ", "nSumL", "nSumP", "nSumShortPL", "nSumLongPL", "nSumPL", "nPL", "nSellP", "nBuyP", "BarTime", "Index"); debugPrintln("\n\n" + sProgram_Name + " on interval " + getInterval() + " for symbol: " + getSymbol()); } function PrintTradeValues(...args){ // Pass comma separated arguments, the 1st value is at the end of output, so the last var ArgArray = args; // value is on the left next to the bar index that's printed by default...see below. var PrintIndex = true; var TempArray = []; var nIndex = 0; var sFirstArgument = ArgArray[0]; Obj.aTradesArray[Obj.nTradesArrayIndex] = ""; ArgArray.forEach(function(current_value){ TempArray[nIndex] = ""; if(PrintIndex && current_value === "Index") PrintIndex = false; if(current_value === null || current_value === true || current_value === false || isNaN(current_value)){ if(current_value === "Index" || current_value != null && current_value === current_value.toString() && current_value.length > 7){ debugPrint(current_value + "\t"); if(current_value === "Index") TempArray[nIndex] = "\n" + current_value + "\t"; else if(sFirstArgument != "StopLossTrades" || Obj.bPrintHeader == true) TempArray[nIndex] = current_value + "\t"; }else{ debugPrint(current_value + "\t\t"); if(sFirstArgument != "StopLossTrades" || Obj.bPrintHeader == true) TempArray[nIndex] = current_value + "\t\t"; } }else if(nIndex < 3 || (nIndex > 4 && nIndex < 8)){ debugPrint(" " + current_value + "\t\t") TempArray[nIndex] = " " + current_value + "\t\t"; }else{ debugPrint(current_value.toFixed(2) + "\t\t"); TempArray[nIndex] = current_value.toFixed(2) + "\t\t"; } nIndex++; }) if(PrintIndex){ debugPrintln(getCurrentBarIndex() + "\t"); TempArray[nIndex] = getCurrentBarIndex() + "\t"; }else{ debugPrintln(); } if(Obj.bInit && (sFirstArgument != "StopLossTrades" || Obj.bPrintHeader == true)){ for(var c = nIndex; c >= 0; c--){ if(TempArray[c] != undefined) Obj.aTradesArray[Obj.nTradesArrayIndex] += TempArray[c]; } Obj.nTradesArrayIndex++; } } function PrintValues(...args){ // Pass comma separated arguments, the 1st value is at the end of output, so the last var ArgArray = args; // value is on the left next to the bar index that's printed by default...see below. var PrintIndex = true; ArgArray.forEach(function(current_value){ if(PrintIndex && current_value === "Index") PrintIndex = false; if(current_value === null || current_value === true || current_value === false || isNaN(current_value)){ if(current_value === "Index" || current_value != null && current_value === current_value.toString() && current_value.length > 7) debugPrint(current_value + "\t"); else debugPrint(current_value + "\t\t"); }else debugPrint(current_value.toFixed(2) + "\t\t"); }) if(PrintIndex){ debugPrintln(getCurrentBarIndex() + "\t"); PrintIndex = true; }else debugPrintln(); } Date.prototype.ToShortTime = function (){ var hours = this.getHours(); var minutes = this.getMinutes(); // var seconds = this.getSeconds(); // var dTimeString = ('0' + hours).slice(-2) + ":" + ('0' + minutes).slice(-2) + ":" + ('0' + seconds).slice(-2); var dTimeString = ('0' + hours).slice(-2) + ":" + ('0' + minutes).slice(-2); return dTimeString; } function DoAlerts(bAlertOn, bPlayAlert, sProgram_Name, WaveFile){ if(!bAlertOn || !bPlayAlert) return; else if(isLastBarOnChart()){ Alert.playSound(WaveFile); debugPrintln("\nAlert from: " + sProgram_Name + " on interval " + getInterval() + " for symbol: " + getSymbol()); } } function GetPrice(bBuyer, nPrice){ // Round nPrice to nearest 0.25 based on if buy or sell if(bBuyer) return Math.floor(nPrice) + Math.ceil((nPrice - Math.floor(nPrice))/0.25)*0.25; else return Math.floor(nPrice) + Math.floor((nPrice - Math.floor(nPrice))/0.25)*0.25; } function PrintTradesArray(Obj){ // This prints all of the streamed trades saved to Obj.aTradesArray // for(var c = Obj.aTradesArray.length - 1; c >= 0; c--){ // For the newest values to be on the bottom. for(var c = 0; c < Obj.aTradesArray.length; c++){ // For the newest values to be on the top. debugPrintln(Obj.aTradesArray[c]); } } function PrintObjectValues(Obj){ // This prints the current value of every variable in the global variable object except for the array. // The array(s) must be the last variables in the object because the break statement exits the for loop. for(var i in Obj){ if(Array.isArray(Obj[i])) break; else debugPrintln(Obj[i]); } }