/// <summary> /// Validate Trade on the Bollinger /// </summary> /// <param name="strategyData"></param> /// <param name="decisiontype"></param> /// <returns></returns> public bool IsTradeValidOnBollinger(StrategyData strategyData, StrategyDecision decisiontype, decimal BollingerFactor, decimal Reward, [CallerMemberName] string CallingDecision = "") { if (!ValidationRequired(CallingDecision)) { return(true); } if (decisiontype != StrategyDecision.Buy && decisiontype != StrategyDecision.Sell) { //invalid decision input return(false); } if (decisiontype == StrategyDecision.Buy) { //top crossed recently so chances of loss higher with buy if (strategyData.BollTopCrossed) { return(false); } //no buy trades from below the middle bollinger by 0.10% #this is a reversal zone if (strategyData.BollingerMiddle > strategyData.currentClose && Math.Abs(strategyData.BollingerMiddlePercentage) <= 0.10m) { return(false); } if (strategyData.BollingerUpperPercentage >= (Reward * BollingerFactor)) { return(true); } return(false); } if (decisiontype == StrategyDecision.Sell) { //bottom crossed recently so chances of loss higer with sell if (strategyData.BollBottomCrossed) { return(false); } //no sell trades from above the middle bollinger by 0.10% #this is a reversal zone if (strategyData.BollingerMiddle < strategyData.currentClose && Math.Abs(strategyData.BollingerMiddlePercentage) <= 0.10m) { return(false); } if (strategyData.BollingerLowerPercentage >= (Reward * BollingerFactor)) { return(true); } return(false); } return(false); }
private int GetDecisionStrength(StrategyDecision decision) { switch (decision) { case StrategyDecision.Open: return(OpenPositionSignalStrength); case StrategyDecision.OpenMissed: return(MissedPositionSignalStrength); case StrategyDecision.ExitHeavy: return(ExitPositionHeavyLossSignalStrength); case StrategyDecision.Exit: return(ExitSignalStrength); case StrategyDecision.TakeProfit: return(TakeProfitSignalStrength); case StrategyDecision.Escape: return(EscapeTrapSignalStrength); default: return(-1); } }
/// <summary> /// Validate for consecutive dropping or rising kandles /// </summary> public bool IsKandleConsistent(StrategyData strategyData, StrategyDecision decisiontype, int lookback, [CallerMemberName] string CallingDecision = "") { if (!ValidationRequired(CallingDecision)) { return(true); } if (decisiontype != StrategyDecision.Buy && decisiontype != StrategyDecision.Sell) { //invalid value for decision return(false); } var kandleslice = strategyData.kandles.Skip(strategyData.kandles.Count - lookback).Take(lookback); for (int i = 0; i < kandleslice.Count() - 1; i++) { if (kandleslice.ElementAt(i).Open > kandleslice.ElementAt(i + 1).Open&& decisiontype == StrategyDecision.Buy) { return(false); } if (kandleslice.ElementAt(i).Open < kandleslice.ElementAt(i + 1).Open&& decisiontype == StrategyDecision.Sell) { return(false); } } return(true); }
/// <summary> /// Validate Buy & Sell is following the trend /// </summary> /// <param name="strategyData"></param> /// <param name="decisiontype"></param> /// <param name="CallingDecision"></param> /// <returns></returns> public bool IsTradeMatchTrend(StrategyData strategyData, StrategyDecision decisiontype, [CallerMemberName] string CallingDecision = "") { if (!ValidationRequired(CallingDecision)) { return(true); } if (decisiontype != StrategyDecision.Buy && decisiontype != StrategyDecision.Sell) { //invalid decision input return(false); } if (decisiontype == StrategyDecision.Buy) { if (strategyData.trend != "BULLISH" && strategyData.mood != "BULLISH") { return(false); } } if (decisiontype == StrategyDecision.Sell) { if (strategyData.trend != "BEARISH" && strategyData.mood != "BEARISH") { return(false); } } return(true); }
public void ResetCounters() { BuyCounter = 0; SellCounter = 0; prevDecision = StrategyDecision.None; prevDecisionType = StrategyDecision.None; LatestSignalStrength = 0; }
private bool OpenMissedPosition(SimplePosition position, ref StrategyData strategyData) { //position already exists if (position.PositionType != PositionType.None) { return(false); } //in middle of a decision if (strategyData.isBuy || strategyData.isSell) { return(false); } //no historical data available if (string.IsNullOrEmpty(strategyData.histdata)) { return(false); } //invalid historical data StrategyDecision signaldecision = StrategyDecision.None; int signalperiod = -1; GetSignalData(strategyData, ref signaldecision, ref signalperiod); if (signaldecision == StrategyDecision.None || signalperiod == -1) { return(false); } //missed buy position if (signaldecision == StrategyDecision.Buy && signalperiod >= MissedPositionStartCandleIndex && signalperiod <= MissedPositionEndCandleIndex)//3,5,200 { strategyData.Decision = StrategyDecision.OpenMissed; strategyData.DecisionType = StrategyDecision.Buy; return(true); } //missed sell position if (signaldecision == StrategyDecision.Sell && signalperiod >= MissedPositionStartCandleIndex && signalperiod <= MissedPositionEndCandleIndex)//3,5,200 { strategyData.Decision = StrategyDecision.OpenMissed; strategyData.DecisionType = StrategyDecision.Sell; return(true); } return(false); }
private bool EscapeTrap(SimplePosition position, ref StrategyData strategyData) { //no open positions if (position.PositionType == PositionType.None) { return(false); } //no historical decisions available if (string.IsNullOrEmpty(strategyData.histdata)) { return(false); } //in middle of decision if (strategyData.isBuy || strategyData.isSell) { return(false); } //invalid historical data StrategyDecision signaldecision = StrategyDecision.None; int signalperiod = -1; GetSignalData(strategyData, ref signaldecision, ref signalperiod); if (signaldecision == StrategyDecision.None || signalperiod == -1) { return(false); } //the bot is trapped with sell position!! if (position.PositionType == PositionType.Sell && signaldecision == StrategyDecision.Buy && signalperiod >= EscapeTrapCandleIdx)//3,300 { strategyData.Decision = StrategyDecision.Escape; strategyData.DecisionType = StrategyDecision.Buy; return(true); } //the bot is trapped with buy position if (position.PositionType == PositionType.Buy && signaldecision == StrategyDecision.Sell && signalperiod >= EscapeTrapCandleIdx)//3,300 { strategyData.Decision = StrategyDecision.Escape; strategyData.DecisionType = StrategyDecision.Sell; return(true); } return(false); }
/// <summary> /// Validate Buy On Green and Sell On Red /// </summary> /// <param name="strategyData"></param> /// <param name="decisiontype"></param> /// <returns></returns> public bool IsTradeOnRightKandle(StrategyData strategyData, StrategyDecision decisiontype, StrategyDecision positiondecision, [CallerMemberName] string CallingDecision = "") { if (!ValidationRequired(CallingDecision)) { return(true); } if (decisiontype != StrategyDecision.Buy && decisiontype != StrategyDecision.Sell && positiondecision != StrategyDecision.Open && positiondecision != StrategyDecision.OpenMissed && positiondecision != StrategyDecision.Exit && positiondecision != StrategyDecision.Escape) { return(false); } if (decisiontype == StrategyDecision.Buy && (positiondecision == StrategyDecision.Open || positiondecision == StrategyDecision.OpenMissed)) { //buy on green if (strategyData.currentClose > strategyData.currentOpen && strategyData.currentClose > strategyData.PrevOpen) { return(true); } } if (decisiontype == StrategyDecision.Sell && (positiondecision == StrategyDecision.Open || positiondecision == StrategyDecision.OpenMissed)) { //sell on red if (strategyData.currentClose < strategyData.currentOpen && strategyData.currentClose < strategyData.PrevOpen) { return(true); } } if (decisiontype == StrategyDecision.Buy && (positiondecision == StrategyDecision.Exit || positiondecision == StrategyDecision.Escape)) { if (strategyData.currentClose > strategyData.currentOpen) { return(true); } } if (decisiontype == StrategyDecision.Sell && (positiondecision == StrategyDecision.Exit || positiondecision == StrategyDecision.Escape)) { if (strategyData.currentClose < strategyData.currentOpen) { return(true); } } return(false); }
private void GetSignalData(StrategyData strategyData, ref StrategyDecision decision, ref int period) { var signaldata = Convert.ToString(strategyData.histdata.Split(' ').Last()); if (signaldata.Contains("B")) { decision = StrategyDecision.Buy; } if (signaldata.Contains("S")) { decision = StrategyDecision.Sell; } period = Convert.ToInt32(signaldata.Replace("B", "").Replace("S", "")); }
/// <summary> /// Validate the signal quality for buy or sell decision /// </summary> /// <param name="strategyData"></param> /// <param name="decisiontype"></param> /// <param name="RequiredSignalQuality"></param> /// <param name="CallingDecision"></param> /// <returns></returns> public bool IsSignalGoodQuality(StrategyData strategyData, StrategyDecision decisiontype, int RequiredSignalQuality, [CallerMemberName] string CallingDecision = "") { if (!ValidationRequired(CallingDecision)) { return(true); } if (decisiontype != StrategyDecision.Buy && decisiontype != StrategyDecision.Sell) { //invalid decision input return(false); } return(strategyData.SignalQuality >= RequiredSignalQuality); }
public OpenCloseStrategyDecision() { //decision strength variables BuyCounter = 0; SellCounter = 0; prevDecision = StrategyDecision.None; prevDecisionType = StrategyDecision.None; AllDecisions = new HashSet <StrategyDecision> { StrategyDecision.Open, StrategyDecision.OpenMissed, StrategyDecision.TakeProfit, StrategyDecision.ExitHeavy, StrategyDecision.Exit, StrategyDecision.Escape }; //missedposition decision variables MissedPositionStartCandleIndex = OpenCloseStrategySettings.settings.MissedPositionStartCandleIndex; MissedPositionEndCandleIndex = OpenCloseStrategySettings.settings.MissedPositionEndCandleIndex; //heavyloss decision variables ExitImmediate = OpenCloseStrategySettings.settings.ExitImmediate; HeavyRiskPercentage = OpenCloseStrategySettings.settings.HeavyRiskPercentage; //escape decision variables //EscapeTraps = OpenCloseStrategySettings.settings.EscapeTraps; EscapeTrapCandleIdx = OpenCloseStrategySettings.settings.EscapeTrapCandleIdx; //set variables to avoid wrong trades (trade validation) RequiredSignalGap = OpenCloseStrategySettings.settings.SignalGap; BollingerFactor = OpenCloseStrategySettings.settings.BollingerFactor; RequiredSignalQuality = OpenCloseStrategySettings.settings.RequiredSignalQuality; ConsistentKandlesLookBack = OpenCloseStrategySettings.settings.ConsistentKandlesLookBack; ValidationRuleSet = OpenCloseStrategySettings.settings.ValidationRuleSet; //ruleset DecisionSet = new HashSet <string>(OpenCloseStrategySettings.settings.DecisionSet.Split(',')); //decisionset validator = new TradeValidator(ValidationRuleSet); //decision signal strengths OpenPositionSignalStrength = OpenCloseStrategySettings.settings.OpenPositionSignalStrength; MissedPositionSignalStrength = OpenCloseStrategySettings.settings.MissedPositionSignalStrength; ExitPositionHeavyLossSignalStrength = OpenCloseStrategySettings.settings.ExitPositionHeavyLossSignalStrength; ExitSignalStrength = OpenCloseStrategySettings.settings.ExitSignalStrength; TakeProfitSignalStrength = OpenCloseStrategySettings.settings.TakeProfitSignalStrength; EscapeTrapSignalStrength = OpenCloseStrategySettings.settings.EscapeTrapSignalStrength; }
//validations for the decisions made private bool IsDecisionStrong(int signalStrength, StrategyDecision Decision, StrategyDecision DecisionType) { LatestSignalStrength = signalStrength; //simple logic of current and previous states match if (prevDecision != Decision || prevDecisionType != DecisionType) { BuyCounter = 0; SellCounter = 0; prevDecision = Decision; prevDecisionType = DecisionType; } if (Decision == prevDecision && DecisionType == prevDecisionType && Decision != StrategyDecision.None && DecisionType != StrategyDecision.None) { if (Decision == StrategyDecision.Open || Decision == StrategyDecision.OpenMissed || Decision == StrategyDecision.TakeProfit || Decision == StrategyDecision.Exit || Decision == StrategyDecision.Escape || Decision == StrategyDecision.ExitHeavy) { if (DecisionType == StrategyDecision.Buy) { ++BuyCounter; return(BuyCounter >= signalStrength); } if (DecisionType == StrategyDecision.Sell) { ++SellCounter; return(SellCounter >= signalStrength); } } } return(false); }
private bool RunDecision(SimplePosition position, ref StrategyData strategyData, StrategyDecision decision, RobotInput robotInput) { if (!DecisionSet.Contains(decision.ToString())) { return(false); } if (decision == StrategyDecision.Open) { return(OpenPosition(position, ref strategyData)); } else if (decision == StrategyDecision.OpenMissed) { return(OpenMissedPosition(position, ref strategyData)); } else if (decision == StrategyDecision.ExitHeavy) { return(ExitPositionHeavyLoss(position, ref strategyData)); } else if (decision == StrategyDecision.Exit) { return(ExitPosition(position, ref strategyData, robotInput.risk)); } else if (decision == StrategyDecision.TakeProfit) { return(TakeProfit(position, ref strategyData, robotInput.reward)); } else if (decision == StrategyDecision.Escape) { return(EscapeTrap(position, ref strategyData)); } else { return(false); } }