private void ApplyNegativeProfitStrategy(Position position, LossStrategy strategy) { if (Params.CandlesInNegativeArea > 0) { int negativeBarsCount = 0; for (int i = positionStartIndex(position) + 1; i < lastBarIndex() - 1; i++) // check only for finished bars { if (IsInNegativeArea(i, position, strategy)) { negativeBarsCount++; } } Func <Position, double> negativeBreakOffset = p => (p.EntryPrice - p.StopLoss.Value) * Params.NegativeBreakEvenOffset; if (position.TradeType == TradeType.Sell) { negativeBreakOffset = p => (p.StopLoss.Value - p.EntryPrice) * -Params.NegativeBreakEvenOffset; } if (negativeBarsCount == Params.CandlesInNegativeArea) { logger.Info(String.Format("Moving Profit to Breakeven as {0}% of original Stop Loss. Reason: {1} candle(s) in negative area", Params.NegativeBreakEvenOffset, negativeBarsCount)); Robot.Print("Moving Profit to Breakeven as {0}% of original Stop Loss. Reason: {1} candle(s) in negative area", Params.NegativeBreakEvenOffset, negativeBarsCount); double newPrice = position.EntryPrice - negativeBreakOffset(position); TradeResult result = Robot.ModifyPosition(position, position.StopLoss, newPrice); if (result.IsSuccessful) { Robot.Print(result.Error); negativeBePositions.Add(position); } else { Robot.Print(result.Error.ToString()); } } } }
public TradeResult Do() { TradeOrder order; if (TradeQueue.Instance.TryDequeue(out order)) { var result = MakeMacth(order); //如果交易未完成,则重新加入待交易队列 if (order.Remain() > 0) { TradeQueue.Instance.Add(order); } return(result); } else { TradeLogger.Instance.Update(); } return(TradeResult.None()); }
protected void CloseSellOrders() { IPosition[] activePositions = Trade.GetActivePositions(magicNumber); if (activePositions != null) { for (int i = activePositions.GetLength(0) - 1; i >= 0; i--) { TradeResult tR = null; if ((int)activePositions[i].Type == (int)ExecutionRule.Sell) { // && activePositions[i].State == OrderState.Executed) tR = Trade.CloseMarketPosition(activePositions[i].Id, activePositions[i].Lots, Instrument.Ask, -1, "Closed on changed TP,SL"); } if (tR == null) { XXPrint("*!* Can't close Sell position {1} at Price {0}", Instrument.Ask, activePositions[i].Id); } } } }
private int OrderSend(TradeType TrdTp, long iVol) { int cd_8 = 0; if (iVol > 0) { TradeResult result = ExecuteMarketOrder(TrdTp, Symbol, iVol, Label, 0, 0, 0, "smart_grid"); if (result.IsSuccessful) { Print(TrdTp, "Opened at: ", result.Position.EntryPrice); cd_8 = 1; } else { Print(TrdTp, "Openning Error: ", result.Error); } } else { Print("Volume calculation error: Calculated Volume is: ", iVol); } return(cd_8); }
protected void SetSellOrder() { double SL = getSL(0); double TP = getTP(0); Stops st = Stops.InPrice(SL, TP); TradeResult r = null; r = Trade.OpenMarketPosition( Instrument.Id, ExecutionRule.Sell, vol, Instrument.Bid, -1, st, "Sell.", magicNumber ); if (r == null) { XXPrint("*!* Can't open Sell position at Price {0}", Instrument.Bid); } }
protected void SetSellOrder() { double SL = Math.Round(Instrument.Ask + StaticStopLoss * Instrument.Point, Instrument.PriceScale); double TP = 0.0; Stops st = Stops.InPrice(SL, TP); TradeResult r = null; r = Trade.OpenMarketPosition( Instrument.Id, ExecutionRule.Sell, vol, Instrument.Bid, -1, st, "Sell.", magicNumber ); if (r == null || !r.IsSuccessful) { XXPrint("*!* Can't open Sell position at Price {0}", Instrument.Bid); } }
protected void SetBuyOrder() { double SL = getSL(1); double TP = getTP(1); Stops st = Stops.InPrice(SL, TP); TradeResult r = null; r = Trade.OpenMarketPosition( Instrument.Id, ExecutionRule.Buy, vol, Instrument.Ask, -1, st, "Buy..", magicNumber ); if (r == null) { XXPrint("*!* Can't open Buy position at Price {0}", Instrument.Ask); } }
protected void setPendingBuyOrder() { double SL = CalculateSL(ExecutionRule.Buy); double TP = CalculateTP(ExecutionRule.Buy); double OP = B1H + Instrument.Spread; if (Instrument.Bid < SL) { SL = Instrument.Bid - (SL - Instrument.Bid) - Instrument.Spread; } if (TP <= OP) { TP = OP + (OP - TP) + Instrument.Spread; } Stops SLTP = Stops.InPrice( SL, TP ); int attempt = 0; TradeResult tR = null; do { attempt++; tR = Trade.OpenPendingPosition(Instrument.Id, ExecutionRule.BuyStop, vol, OP, -1, SLTP, Bars[_CIndex].Time.AddDays(90.0), "buyStop on bar signal", magicNumber); }while ((tR == null? true: !tR.IsSuccessful) && attempt < 100); if ((tR == null? true: !tR.IsSuccessful)) { XXPrint("[{2}>>]{1} Cann't Send BuyStop order on Price {4} at Ask: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); } else { TradeResult ntR = null; do { attempt++; ntR = Trade.UpdatePendingPosition(tR.Position.Id, vol, OP, -1, Bars[_CIndex].Time.AddDays(90.0), SL, TP, "buyStop set SL,TP"); }while ((ntR == null? true: !ntR.IsSuccessful) && attempt < 100); if (ntR == null? true: !ntR.IsSuccessful) { XXPrint("[{2}>>]{1} Cann't Modify BuyStop order on Price {4} at Ask: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); } else { listOfBuyStop.Add(ntR.Position.Id); XXPrint("[{3}>>]{2} Sended successfully BuyStop order for position {0} at Price: {1} ", tR.Position.Id, tR.Position.OpenPrice, Bars[_CIndex].Time, Instrument.Name); } } }
private void HandleTradeResult(TradeResult result, JObject order) { if (result.IsSuccessful) { if (result.Position != null) { var p = result.Position; JObject o = new JObject( new JProperty("cmd", "position_created_result"), new JProperty("_callbackId", order.ContainsKey("_callbackId") ? (string)order["_callbackId"] : null), new JProperty("payload", new JObject( new JProperty("label", p.Label), new JProperty("_id", p.Id), new JProperty("id", p.Label.Split('|')[0]), new JProperty("symbol", p.SymbolCode.ToLower()), new JProperty("openprice", p.EntryPrice), new JProperty("etime", p.EntryTime.ToUnixTime()), new JProperty("sl", p.StopLoss), new JProperty("tp", p.TakeProfit) ))); _publishMessage(o); } else if (result.PendingOrder != null) { JObject o = new JObject( new JProperty("cmd", "order_created_result"), new JProperty("_callbackId", order.ContainsKey("_callbackId") ? (string)order["_callbackId"] : null), new JProperty("payload", new JObject( new JProperty("label", result.PendingOrder.Label), new JProperty("_id", result.PendingOrder.Id), new JProperty("id", result.PendingOrder.Label.Split('|')[0]) ) )); _publishMessage(o); } } else { JObject o = new JObject( new JProperty("cmd", "order_create_failed_result"), new JProperty("_callbackId", order.ContainsKey("_callbackId") ? (string)order["_callbackId"] : null), new JProperty("payload", new JObject( new JProperty("label", (string)order["label"]) ) )); _publishMessage(o); } }
public TradeResult MiddleOrderFlip(Trade trade) { // Take Profit Stop Loss Trailing Stop Loss decimal middle = build.TakeProfitPrice - ((build.TakeProfitPrice - build.StopLossPrice) / 2); bool active = true; bool canceledSwap = false; bool take = true; bool initial = true; bool trailingTake = false; int iterationCanceled = 0; int priceDecimal = BitConverter.GetBytes(decimal.GetBits(trade.StopLossPrice)[3])[2]; decimal prevStopLossPrice = build.StopLossPrice; decimal percentStop = decimal.Round((build.StopLossPrice - build.Price) / build.Price * -1m, 2); TradeResult result = new TradeResult(); using (var client = new BinanceSocketClient()) { var successKline = client.SubscribeToKlineStream(build.Market, KlineInterval.OneMinute, (data) => { if (trade.Status && iterationCanceled == 0) { if (build.TrailingStopLoss) { if (((trade.StopLossPrice - data.Data.High) / data.Data.High * -1) > percentStop) { prevStopLossPrice = trade.StopLossPrice; trade.StopLossPrice = decimal.Round(data.Data.High - (data.Data.High * percentStop), priceDecimal); middle = trade.TakeProfitPrice - ((trade.TakeProfitPrice - trade.StopLossPrice) / 2); } } if (data.Data.Low > middle && !take) { if (!build.TrailingTakeProfit) { Cancel cancel = new Cancel(); if (cancel.Trade(trade)) { canceledSwap = true; Sell sell = new Sell(build, api); trade = sell.Limit(trade, trade.TakeProfitPrice); if (trade.Success) { canceledSwap = false; TradeDB tradeDB = new TradeDB(); tradeDB.Update(trade); take = true; } } } else if (data.Data.High > trade.TakeProfitPrice) { trailingTake = true; } } else if (data.Data.Low <= middle && take || data.Data.Low <= middle && initial || trade.StopLossPrice > prevStopLossPrice && data.Data.Low <= middle) { Cancel cancel = new Cancel(); if (cancel.Trade(trade) || initial) { canceledSwap = true; Sell sell = new Sell(build, api); trade = sell.LimitStop(trade, trade.StopLossPrice); if (trade.Success) { canceledSwap = false; TradeDB tradeDB = new TradeDB(); tradeDB.Update(trade); take = false; } } } initial = false; } }); while (active && !trailingTake) { using (var db = new ApplicationDbContext()) { Trade tradeGrab = db.Trades.Where(t => t.Id == trade.Id).Single(); if (!tradeGrab.Status) { trade.Status = false; } } using (var clientRest = new BinanceClient()) { var orderStatus = clientRest.QueryOrder(build.Market, trade.OrderId); if (orderStatus.Success) { if (orderStatus.Data.Status == OrderStatus.Filled) { result.SellPrice = orderStatus.Data.Price; result.SellOrderId = trade.OrderId; result.TradeId = trade.Id; result.EndTime = DateTime.Now; CalculateResult calculate = new CalculateResult(); result = calculate.PercentDifference(result, trade); result.Success = true; active = false; } if (orderStatus.Data.Status == OrderStatus.Canceled && !canceledSwap) { iterationCanceled++; if (iterationCanceled > 4) { active = false; trade.Status = false; TradeDB tradeDB = new TradeDB(); tradeDB.Update(trade); } System.Threading.Thread.Sleep(5000); } else if (orderStatus.Data.Status != OrderStatus.Canceled) { iterationCanceled = 0; } } } } } if (trailingTake == true) { decimal trailingTakePerc = build.TrailingTakePercent < 0 ? build.TrailingTakePercent * -1m : build.TrailingTakePercent; trade.StopLossPrice = decimal.Round(build.TakeProfitPrice - (build.TakeProfitPrice * (trailingTakePerc / 100)), priceDecimal); trade.IsTrailingTake = true; trade.DisplayType = "TSLVC"; TradeDB tradeDB = new TradeDB(); tradeDB.Update(trade); return(TrailingStopLoss(trade)); } else { return(result); } }
}//OnTick() private void OnCloseAsync(TradeResult tr) { Print("Pos. {0} {1} closed async", tr.Position.Id, tr.Position.TradeType); }
private void PlaceBuyStopOrderCallBack(TradeResult obj) { throw new NotImplementedException(); }
private void ExcuteMarketOrderCallBack(TradeResult obj) { throw new NotImplementedException(); }
private void ModifyOrderCallBack(TradeResult obj) { throw new NotImplementedException(); }
private void ClosePositionCallBack(TradeResult obj) { throw new NotImplementedException(); }
protected void OnModifyTrailingStop(TradeResult tr) { OnTradeOperationComplete(tr, "FAILED to modify TRAILING stop loss: "); }
protected void OnClosePositionComplete(TradeResult tr) { OnTradeOperationComplete(tr, "FAILED to close position: "); }
protected void OnModifyTakeProfitComplete(TradeResult tr) { OnTradeOperationComplete(tr, "FAILED to modify TAKE PROFIT: "); }
private void AnalyzeLevelsOnTick() { int idx = Robot.MarketSeries.Close.Count - 1; foreach (Level level in Levels) { TradeType trade = TradeType.Buy; Func <Level, bool> isLevelCrossed = l => Robot.Symbol.Bid <= l.ActivatePrice; Func <Level, bool> isLevelGoneAway = l => Robot.Symbol.Bid > l.DeactivatePrice; if (level.Direction == Direction.SHORT) { isLevelCrossed = l => Robot.Symbol.Ask >= l.ActivatePrice && !l.LevelActivated; isLevelGoneAway = l => Robot.Symbol.Ask < l.DeactivatePrice && l.LevelActivated; trade = TradeType.Sell; } if (IsLevelTradeable(level) && isLevelCrossed(level)) { level.LevelActivated = true; level.LevelActivatedIndex = idx; level.Traded = true; bool isSpike = IsSpike(level.Direction == Direction.LONG ? TradeType.Sell : TradeType.Buy); Renderer.RenderLevel(level, Paused); double spread = Math.Round(Robot.Symbol.Spread / Robot.Symbol.PipSize, 3); if (spread > Params.MaxSpread) { Robot.Print("Spread is over treshold {0} > {1}", spread, Params.MaxSpread); } if (!Paused && !level.Disabled && !isSpike && spread <= Params.MaxSpread) { double risk = Calculator.GetRisk(Params.PositionSize, Params.FixedRiskAmount); double volume = Calculator.GetVolume(Robot.Symbol.Name, Params.PositionSize, Params.FixedRiskAmount, level.StopLossPips, trade); string label = Utils.PositionLabel(Robot.SymbolName, Params.LevelFileName, Params.StrategyType.ToString()); string comment = "profit=" + risk + "&level=" + level.Label + "&profitPips=" + level.ProfitTargetPips; double maxVolume = Robot.Symbol.NormalizeVolumeInUnits(Robot.Account.FreeMargin * Params.MarginTreshold * Robot.Account.PreciseLeverage, RoundingMode.Down); if (volume < maxVolume) { TradeResult result = Robot.PlaceLimitOrder(trade, Robot.Symbol.Name, volume, level.EntryPrice, label, level.StopLossPips, level.ProfitTargetPips, level.ValidTo, comment); logger.Info(String.Format("Placing Limit Order Entry:{0} SL Pips:{1} Type: {2} Spread: {3}", level.EntryPrice, level.StopLossPips, trade, spread)); Robot.Print("Placing Limit Order Entry:{0} SL Pips:{1} Type: {2} Spread: {3}", level.EntryPrice, level.StopLossPips, trade, spread); logger.Info(String.Format("Order placed for Level {0} Success: {1} Error: {2}", result.PendingOrder.Label, result.IsSuccessful, result.Error)); Robot.Print("Order placed for Level {0} Success: {1} Error: {2}", result.PendingOrder.Label, result.IsSuccessful, result.Error); if (result.IsSuccessful) { SendEmailOrderPlaced(level); } } else { logger.Info(String.Format("Order skipped. Insufficient free margin to open position with {0} units. Max units: {1}", volume, maxVolume)); Robot.Print(String.Format("Order skipped. Insufficient free margin to open position with {0} units. Max units: {1}", volume, maxVolume)); } } else { logger.Info(String.Format("Order skipped. State: Disabled {0} Calendar Event: {1}, Spike: {2}, Spread {3} pips, Free margin: {4}", level.Disabled, Paused, isSpike, spread, Robot.Account.FreeMargin)); Robot.Print("Order skipped. State: Disabled: {0} Calendar Event: {1}, Spike: {2}, Spread: {3} pips, Free margin: {4}", level.Disabled, Paused, isSpike, spread, Robot.Account.FreeMargin); } } if (isLevelGoneAway(level) && level.Traded && !level.LevelDeactivated) { level.LevelDeactivated = true; CancelPendingOrder(level, "Deactivate Level reached"); } } }
private void PlaceSellLimitOrderCallBack(TradeResult obj) { throw new NotImplementedException(); }
private void PositionOpened(TradeResult obj) { //throw new NotImplementedException(); }
public virtual ITradeResult AddSellOrder(IOrderDetails order) { ITradeResult tradeResult = new TradeResult(); lock (SyncRoot) { if (tradingPairs.TryGetValue(order.Pair, out TradingPair tradingPair)) { if (order.Side == OrderSide.Sell && (order.Result == OrderResult.Filled || order.Result == OrderResult.FilledPartially)) { string feesPair = order.FeesCurrency + tradingService.Config.Market; decimal feesPairCurrency = (feesPair == order.Pair) ? order.Fees : 0; decimal feesMarketCurrency = tradingService.CalculateOrderFees(order); decimal amountDifference = order.AmountFilled / tradingPair.Amount; decimal balanceOffset = -feesMarketCurrency; if (!order.IsNormalized || order.Pair.EndsWith(Constants.Markets.USDT)) { balanceOffset += order.Cost; AddBalance(balanceOffset); } else { string normalizedMarket = tradingService.Exchange.GetPairMarket(order.OriginalPair) == Constants.Markets.USDT ? tradingService.Config.Market + tradingService.Exchange.GetPairMarket(order.OriginalPair) : tradingService.Exchange.GetPairMarket(order.OriginalPair) + tradingService.Config.Market; decimal price = tradingService.GetPrice(normalizedMarket, TradePriceType.Ask); decimal amount = (order.Cost - feesMarketCurrency) / price; AddOrUpdatePair(order, normalizedMarket, feesMarketCurrency, feesPairCurrency, amount, price); } decimal sellFees = feesMarketCurrency + tradingPair.Fees * amountDifference; tradingPair.Fees += feesMarketCurrency - sellFees; decimal costDifference = order.Cost - tradingPair.GetPartialCost(order.AmountFilled) - (tradingPair.Metadata.AdditionalCosts ?? 0); decimal profit = costDifference * amountDifference - feesMarketCurrency; if (tradingPair.Amount > order.AmountFilled) { tradingPair.Amount -= order.AmountFilled; if (tradingPair.CurrentCost < tradingService.Config.MinCost) { tradingPair.OrderDates.Clear(); } } else { tradingPairs.TryRemove(order.Pair, out tradingPair); } tradeResult = new TradeResult { IsSuccessful = true, Pair = order.Pair, Amount = order.AmountFilled, OrderDates = tradingPair.OrderDates, AveragePrice = tradingPair.AveragePrice, Fees = sellFees, SellDate = order.Date, SellPrice = order.AveragePrice, BalanceOffset = balanceOffset, Profit = profit, Metadata = order.Metadata, }; } } } return(tradeResult); }
public async Task <TradeResult> Execute(TradingContext context, IExchange exchange) //TODO: Find a better way to create orders etc. Make this a service? { if (ExchangeConfig == null) { return(new TradeResult() { ErrorReason = ErrorReason.NoAccount, ErrorMessage = "No account chosen for " + exchange }); } if (exchange == null) { return(new TradeResult() { ErrorReason = ErrorReason.NoExchange, ErrorMessage = "Exchange doesn't exist for " + exchange }); } if (!exchange.TradingEnabled) { return(new TradeResult() { ErrorReason = ErrorReason.TradingDisabled, ErrorMessage = "Trading is currently disabled on exchange: " + exchange }); } //TODO: Run checks to make sure coins are enabled etc. //TODO: Check that we have enough liquidity for trades (and potentially swap from available liquidity to fill them) //If we start on the base, we want to buy the alt var side = Pair.BaseCurrency == ExistingCurrency ? OrderSide.Buy : OrderSide.Sell; ExchangeOrderResult orderResult; if (Simulated) { orderResult = await exchange.SimulateOrder(Pair.MarketSymbol, side, OrderType.Market, 0, Liquidity, DelayMs); //Use delay to simulate lag between placing and filling the order } else { orderResult = await exchange.CreateOrder(Pair.MarketSymbol, side, OrderType.Market, 0, Liquidity); } TradeResult result = new TradeResult() { Amount = orderResult.Amount, AmountFilled = orderResult.AmountFilled, AveragePrice = orderResult.AveragePrice, Fees = orderResult.Fees, FeesCurrency = orderResult.FeesCurrency, FillDate = orderResult.FillDate, OrderSide = side, MarketSymbol = Pair.MarketSymbol, Message = orderResult.Message, OrderDate = orderResult.OrderDate, OrderId = orderResult.OrderId, Price = orderResult.Price, Result = orderResult.Result.ToOrderResult(), TradeId = orderResult.TradeId }; if (orderResult.Result == ExchangeAPIOrderResult.Canceled || orderResult.Result == ExchangeAPIOrderResult.Error || orderResult.Result == ExchangeAPIOrderResult.Unknown) { result.ErrorReason = ErrorReason.TradeError; result.ErrorMessage = "Something went wrong with order " + orderResult.OrderId + ",\r\nResult:" + orderResult.Result + "\r\n" + orderResult.Message; } return(result); }
// Jumping StopLoss private void JumpingStop(Position position) { double Max = position.Pips - Jumping_Distance; double NewJump = Max - (Max % Jumping_Stop); double NewSL; if (position.TradeType == TradeType.Buy) { NewSL = position.EntryPrice + NewJump * symbol.PipSize; if (NewSL <= position.StopLoss) return; } else { NewSL = position.EntryPrice - NewJump * symbol.PipSize; if (NewSL >= position.StopLoss) return; } result = ModifyPosition(position, NewSL, position.TakeProfit); if (!result.IsSuccessful) Print("ERROR: Setting Jumping Stop!", result.Error); }
protected void setPendingBuyOrder() { if (listOfBuyStop.Count >= MaxQuantityOfBuyOrders) { return; } double CurrentAsk = Instrument.Ask; double CurrentBid = Instrument.Bid; double OP = CalculateOpenPrice(ExecutionRule.BuyStop); if (OP <= (CurrentAsk + 2 * Instrument.Spread)) { OP = Math.Round(CurrentAsk + 3.14 * Instrument.Spread, Instrument.PriceScale); } double SL = CalculateSL(ExecutionRule.BuyStop, OP); if (OP <= SL) { SL = (double)Math.Round(OP - staticSL * Instrument.Point, Instrument.PriceScale); } double TP = CalculateTP(ExecutionRule.BuyStop, OP); if (CurrentAsk <= SL) { SL = (double)Math.Round(CurrentAsk - (CurrentAsk - SL) - 3.14 * Instrument.Spread, Instrument.PriceScale); } if (TP <= OP) { TP = (double)Math.Round(OP + (OP - TP) + 3.14 * Instrument.Spread, Instrument.PriceScale); } Stops SLTP = Stops.InPrice( SL, TP ); int attempt = 0; TradeResult tR = null; do { attempt++; tR = Trade.OpenPendingPosition(Instrument.Id, ExecutionRule.BuyStop, vol, OP, -1, SLTP, Bars[_CIndex].Time.AddDays(60.0), "buyStop on bar signal", magicNumber); }while ((tR == null? true: !tR.IsSuccessful) && attempt < 8); if ((tR == null? true: !tR.IsSuccessful)) { XXPrint("[{2}>>]{1} Cann't Send BuyStop order on Price {3} at Bid: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); } else { TradeResult ntR = null; do { attempt++; ntR = Trade.UpdatePendingPosition(tR.Position.Id, vol, OP, -1, Bars[_CIndex].Time.AddDays(60.0), SL, TP, "buyStop set SL,TP"); }while ((ntR == null? true: !ntR.IsSuccessful) && attempt < 8); if (ntR == null? true: !ntR.IsSuccessful) { XXPrint("[{2}>>]{1} Cann't modify BuyStop order on Price {3} at Bid: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); attempt = 0; do { attempt++; ntR = Trade.CancelPendingPosition(tR.Position.Id); }while((ntR == null? true: !ntR.IsSuccessful) && attempt < 8); if (ntR == null? true: !ntR.IsSuccessful) { XXPrint("[*EC*{2}>>]{1} Cann't cancel strange BuyStop order on Price {3} at Bid: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); } } else { listOfBuyStop.Add(ntR.Position.Id); XXPrint("[{3}>>]{2} Sended successfully BuyStop order for position {0} at Price: {1} ", tR.Position.Id, tR.Position.OpenPrice, Bars[_CIndex].Time, Instrument.Name); } } }
public TradeResult TrailingStopLoss(Trade trade) { bool canceledSwap = false; int iterationCanceled = 0; bool active = true; int priceDecimal = BitConverter.GetBytes(decimal.GetBits(trade.StopLossPrice)[3])[2]; decimal prevStopLossPrice = build.StopLossPrice; decimal percentStop = decimal.Round((build.StopLossPrice - build.Price) / build.Price * -1, 3); TradeResult result = new TradeResult(); using (var client = new BinanceSocketClient()) { var successKline = client.SubscribeToKlineStream(build.Market, KlineInterval.OneMinute, (data) => { if (trade.Status && iterationCanceled == 0) { decimal newPercentDiff = decimal.Round((trade.StopLossPrice - data.Data.High) / data.Data.High, 3); newPercentDiff = newPercentDiff < 0 ? newPercentDiff * -1m : newPercentDiff; if (newPercentDiff > percentStop) { trade.StopLossPrice = decimal.Round(data.Data.High - (data.Data.High * percentStop), priceDecimal); Cancel cancel = new Cancel(); if (cancel.Trade(trade)) { canceledSwap = true; Sell sell = new Sell(build, api); trade = sell.LimitStop(trade, trade.StopLossPrice); if (trade.Success) { canceledSwap = false; TradeDB tradeDB = new TradeDB(); tradeDB.Update(trade); } } } } }); while (active) { using (var db = new ApplicationDbContext()) { Trade tradeGrab = db.Trades.Where(t => t.Id == trade.Id).Single(); if (!tradeGrab.Status) { trade.Status = false; } } using (var clientRest = new BinanceClient()) { var orderStatus = clientRest.QueryOrder(build.Market, trade.OrderId); if (orderStatus.Success) { if (orderStatus.Data.Status == OrderStatus.Filled) { result.SellPrice = orderStatus.Data.Price; result.SellOrderId = trade.OrderId; result.TradeId = trade.Id; result.EndTime = DateTime.Now; CalculateResult calculate = new CalculateResult(); result = calculate.PercentDifference(result, trade); result.Success = true; active = false; } if (orderStatus.Data.Status == OrderStatus.Canceled && !canceledSwap) { iterationCanceled++; if (iterationCanceled > 4) { active = false; trade.Status = false; TradeDB tradeDB = new TradeDB(); tradeDB.Update(trade); } System.Threading.Thread.Sleep(5000); } else if (orderStatus.Data.Status != OrderStatus.Canceled) { iterationCanceled = 0; } } } } } return(result); }
protected void TrailActiveOrders() { double CurrentAsk = Instrument.Ask; double CurrentBid = Instrument.Bid; bool TrailSLTP = true; if ((CurrentAsk == double.NaN) || (CurrentBid == double.NaN)) { XXPrint("!!! {0} - NaNs in main data... Very-very bad :(...", DateTime.Now.ToString("o")); return; } double CurrentBuySL = CalculateSL(ExecutionRule.Buy, Instrument.Ask); double CurrentSellSL = CalculateSL(ExecutionRule.Sell, Instrument.Bid); double CurrentBuyTP = CalculateTP(ExecutionRule.Buy, Instrument.Bid); double CurrentSellTP = CalculateTP(ExecutionRule.Sell, Instrument.Ask); IPosition[] activePositions = Trade.GetActivePositions(magicNumber); if (activePositions != null && activePositions.Length > 0) { for (int i = activePositions.Length - 1; i >= 0; i--) { TradeResult tR = null; int attempts = 0; if ((int)activePositions[i].Type == (int)ExecutionRule.Buy) { if (TrailSLTP) { if ((activePositions[i].TakeProfit != CurrentBuyTP) || (activePositions[i].StopLoss != CurrentBuySL)) { if ((CurrentBid >= CurrentBuyTP) || (CurrentBid <= CurrentBuySL)) { do { attempts++; tR = Trade.CloseMarketPosition(activePositions[i].Id, activePositions[i].Lots, CurrentBid, -1, "Closed on changed TP,SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't close position {0} => attempt to set TP = {2} SL={1} with Bid = {3}", activePositions[i].Id, CurrentBuySL, CurrentBuyTP, CurrentBid); } } else { do { attempts++; tR = Trade.UpdateMarketPosition(activePositions[i].Id, CurrentBuySL, CurrentBuyTP, "trail Buy TP,SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't modify position {0} => attempt to set TP = {2} SL = {1}", activePositions[i].Id, CurrentBuySL, CurrentBuyTP); } } } } else { if (activePositions[i].StopLoss != CurrentBuySL) { if (CurrentBid <= CurrentBuySL) { do { attempts++; tR = Trade.CloseMarketPosition(activePositions[i].Id, activePositions[i].Lots, CurrentBid, -1, "Closed on changed SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't close position {0} => attempt to set SL={1} with Bid = {2}", activePositions[i].Id, CurrentBuySL, Instrument.Bid); } } else { do { attempts++; tR = Trade.UpdateMarketPosition(activePositions[i].Id, CurrentBuySL, activePositions[i].TakeProfit, "trail Buy SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't modify position {0} => attempt to set SL = {1}", activePositions[i].Id, CurrentBuySL); } } } } } if ((int)activePositions[i].Type == (int)ExecutionRule.Sell) { if (TrailSLTP) { if ((activePositions[i].TakeProfit != CurrentSellTP) || (activePositions[i].StopLoss != CurrentSellSL)) { if ((CurrentAsk <= CurrentSellTP) || (CurrentAsk >= CurrentSellSL)) { do { attempts++; tR = Trade.CloseMarketPosition(activePositions[i].Id, activePositions[i].Lots, CurrentAsk, -1, "Closed on changed TP,SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't close position {0} => attempt to set TP = {2} SL={1} with Ask = {3}", activePositions[i].Id, CurrentSellSL, CurrentSellTP, Instrument.Ask); } } else { do { attempts++; tR = Trade.UpdateMarketPosition(activePositions[i].Id, CurrentSellSL, CurrentSellTP, "trail Sell TP,SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't modify position {0} => attempt to set TP = {2} SL = {1}", activePositions[i].Id, CurrentSellSL, CurrentSellTP); } } } } else { if (activePositions[i].StopLoss != CurrentSellSL) { if (CurrentAsk >= CurrentSellSL) { do { attempts++; tR = Trade.CloseMarketPosition(activePositions[i].Id, activePositions[i].Lots, CurrentAsk, -1, "Closed on changed SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't close position {0} => attempt to set SL={1} with Ask = {2}", activePositions[i].Id, CurrentSellSL, CurrentAsk); } } else { do { attempts++; tR = Trade.UpdateMarketPosition(activePositions[i].Id, CurrentSellSL, activePositions[i].TakeProfit, "trail Sell SL"); }while((tR == null? true: !tR.IsSuccessful) && (attempts < 8)); if (tR == null? true: !tR.IsSuccessful) { XXPrint(" *!* Can't modify position {0} => attempt to set SL = {1}", activePositions[i].Id, CurrentBuySL); } } } } } } } }
private async Task ElicitConditions() { var implementConditions = Task.Run(async() => { if (!build.StopLoss && !build.TakeProfit) { // Buy Only --------------------------------------------------------------------- Done trade.DisplayType = "BOVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); } else if (!build.StopLoss && build.TakeProfit && !build.TrailingTakeProfit) { // Take Profit // --------------------------------------------------------------------- Done Sell sell = new Sell(build, api); trade = await sell.LimitAsync(trade, build.TakeProfitPrice); if (trade.Success) { trade.DisplayType = "TPVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); Scan scan = new Scan(build); TradeResult result = await scan.ConclusionTakeProfitAsync(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } } } else if (!build.StopLoss && build.TakeProfit && build.TrailingTakeProfit) { // Take Profit // Trailing Take Profit // --------------------------------------------------------------------- Done int priceDecimal = BitConverter.GetBytes(decimal.GetBits(trade.TakeProfitPrice)[3])[2]; decimal tempTakeProfitPrice = decimal.Round(build.TakeProfitPrice * 2, priceDecimal); Sell sell = new Sell(build, api); trade = await sell.LimitAsync(trade, tempTakeProfitPrice); if (trade.Success) { trade.TakeProfitPrice = build.TakeProfitPrice; trade.DisplayType = "TPVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); Scan scan = new Scan(build, api); TradeResult result = scan.TrailingTakeProfit(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } } } else if (build.StopLoss && !build.TrailingStopLoss && !build.TakeProfit) { // Stop Loss // --------------------------------------------------------------------- Done Sell sell = new Sell(build, api); trade = await sell.LimitStopAsync(trade, build.StopLossPrice); if (trade.Success) { trade.DisplayType = "SLVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); Scan scan = new Scan(build, api); TradeResult result = await scan.ConclusionStopLossAsync(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } } } else if (build.StopLoss && build.TrailingStopLoss && !build.TakeProfit) { // Stop Loss // Trailing Stop Loss // --------------------------------------------------------------------------------------- Done Sell sell = new Sell(build, api); trade = await sell.LimitStopAsync(trade, trade.StopLossPrice); if (trade.Success) { trade.DisplayType = "TSLVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); var trailingStop = Task.Run(async() => { Scan scan = new Scan(build, api); TradeResult result = scan.TrailingStopLoss(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } }); } } else if (build.StopLoss && build.TakeProfit && !build.TrailingStopLoss && !build.TrailingTakeProfit) { // Stop Loss // Take Profit // --------------------------------------------------------------------------------------- Done Sell sell = new Sell(build, api); trade = await sell.LimitAsync(trade, build.TakeProfitPrice); if (trade.Success) { trade.DisplayType = "TPSLVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); var scanStop = Task.Run(async() => { Scan scan = new Scan(build, api); TradeResult result = scan.MiddleOrderFlip(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } }); } } else if (build.StopLoss && build.TakeProfit && build.TrailingStopLoss && !build.TrailingTakeProfit) { // Stop Loss // Take Profit // Trailing Stop Loss // Sell sell = new Sell(build, api); trade = await sell.LimitAsync(trade, build.TakeProfitPrice); if (trade.Success) { trade.DisplayType = "TPSLVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); var scanStop = Task.Run(async() => { Scan scan = new Scan(build, api); TradeResult result = scan.MiddleOrderFlip(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } }); } } else if (build.StopLoss && build.TakeProfit && !build.TrailingStopLoss && build.TrailingTakeProfit) { // Stop Loss // Take Profit // Trailing Take Profit Sell sell = new Sell(build, api); trade = await sell.LimitAsync(trade, build.TakeProfitPrice); if (trade.Success) { trade.DisplayType = "TPSLVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); var scanStop = Task.Run(async() => { Scan scan = new Scan(build, api); TradeResult result = scan.MiddleOrderFlip(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } }); } } else if (build.StopLoss && build.TakeProfit && build.TrailingStopLoss && build.TrailingTakeProfit) { // Stop Loss // Take Profit // Trailing Stop Loss // Trailing Take Profit Sell sell = new Sell(build, api); trade = await sell.LimitAsync(trade, build.TakeProfitPrice); if (trade.Success) { trade.DisplayType = "TPSLVC"; TradeDB tradeDB = new TradeDB(); await tradeDB.UpdateAsync(trade); var scanStop = Task.Run(async() => { Scan scan = new Scan(build, api); TradeResult result = scan.MiddleOrderFlip(trade); trade.Status = false; await tradeDB.UpdateAsync(trade); if (result.Success) { TradeResultDB resultDB = new TradeResultDB(); resultDB.Add(result); } }); } } }); }
// Set a BreakEven sl at "BreakEven_Profit" after reaching "BreakEven_After" private void BreakEven(Position position, double BE_Profit) { double BE_Price; if (position.TradeType == TradeType.Buy) { BE_Price = RND(position.EntryPrice + BE_Profit * symbol.PipSize); if (!(position.StopLoss >= BE_Price) && BE_Price < Bid) { result = ModifyPosition(position, BE_Price, position.TakeProfit); if (!result.IsSuccessful) Print("ERROR: Setting BreakEven!", result.Error); } } else { BE_Price = RND(position.EntryPrice - BE_Profit * symbol.PipSize); if (!(position.StopLoss <= BE_Price) && BE_Price > Ask) { result = ModifyPosition(position, BE_Price, position.TakeProfit); if (!result.IsSuccessful) Print("ERROR: Setting BreakEven!", result.Error); } } }
public TradeResult PercentDifference(TradeResult result, Trade trade) { result.PercentDiff = (result.SellPrice - trade.BuyPrice) / trade.BuyPrice * 100; return(result); }
// Close half the position when "Take_Profit_1" is reached private void TakeProfit1(Position position) { if (position.Pips >= TakeProfit_1) { long Close_Lots = Symbol.NormalizeVolume(position.Volume / 2); for (i = 0; i < Partial_Positions.Count; i++) if (Partial_Positions[i] == position.Id) return; // Make sure the position is divisible (not 0.01 lots) if (Close_Lots != position.Volume) { result = ClosePosition(position, Close_Lots); if (!result.IsSuccessful) Print("ERROR: Closing Half Position!", result.Error); else { Partial_Positions.Add(position.Id); using (System.IO.StreamWriter file = new System.IO.StreamWriter(FileName, true)) file.WriteLine(position.Id); } } } }
protected void TrailPendingOrders() { double OP = 0.0; double CurrentAsk = Instrument.Ask; double CurrentBid = Instrument.Bid; if ((CurrentAsk == double.NaN) || (CurrentBid == double.NaN)) { XXPrint("!!! {0} - NaNs in main data... Very-very bad :(...", DateTime.Now.ToString("o")); return; } foreach (Guid pos in listOfBuyStop) { IPosition position = Trade.GetPosition(pos); if (position == null) { listOfBuyStop.Remove(pos); continue; } if ((int)position.Type == (int)ExecutionRule.Buy) { XXPrint("BuyStop {0} opened ....", position.Id); listOfBuyStop.Remove(pos); continue; } TradeResult ntR = null; int attempts = 0; OP = CalculateOpenPrice(ExecutionRule.BuyStop); if (OP <= (CurrentAsk + 2 * Instrument.Spread)) { OP = Math.Round(CurrentAsk + 3.14 * Instrument.Spread, Instrument.PriceScale); } double SL = CalculateSL(ExecutionRule.BuyStop, OP); //position.StopLoss==null? (OP - staticSL * Instrument.Point): (double)position.StopLoss; double TP = Math.Round(CalculateTP(ExecutionRule.BuyStop, OP), Instrument.PriceScale); if (OP <= SL) { SL = (double)Math.Round(OP - staticSL * Instrument.Point, Instrument.PriceScale); } if (TP <= OP) { TP = (double)Math.Round(OP + 6.28 * Instrument.Spread, Instrument.PriceScale); } do { attempts++; ntR = Trade.UpdatePendingPosition(position.Id, position.Lots, OP, -1, position.ExpireTime, //Bars[_CIndex].Time.AddDays(90.0), SL, TP, "buyStop set OP"); }while ((ntR == null? true: !ntR.IsSuccessful) && attempts < 8); if (ntR == null? true: !ntR.IsSuccessful) { XXPrint("[{2}>>]{1} Cann't modify BuyStop order on Price {3} at Bid: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); attempts = 0; do { attempts++; ntR = Trade.CancelPendingPosition(position.Id); }while((ntR == null? true: !ntR.IsSuccessful) && attempts < 8); if (ntR == null? true: !ntR.IsSuccessful) { XXPrint("[*EC*{2}>>]{1} Cann't cancel strange BuyStop order on Price {3} at Bid: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); } else { listOfBuyStop.Remove(position.Id); } } else { XXPrint("[{3}>>]{2} Modified successfully BuyStop order for position {0} at Price: {1} ", ntR.Position.Id, ntR.Position.OpenPrice, Bars[_CIndex].Time, Instrument.Name); } } foreach (Guid pos in listOfSellStop) { IPosition position = Trade.GetPosition(pos); if (position == null) { listOfSellStop.Remove(pos); continue; } if ((int)position.Type == (int)ExecutionRule.Sell) { XXPrint("SellStop {0} opened ....", position.Id); listOfSellStop.Remove(pos); continue; } TradeResult ntR = null; int attempts = 0; OP = CalculateOpenPrice(ExecutionRule.SellStop); if (OP >= (CurrentBid - 2 * Instrument.Spread)) { OP = Math.Round(CurrentBid - 3.14 * Instrument.Spread, Instrument.PriceScale); } double SL = CalculateSL(ExecutionRule.SellStop, OP); //position.StopLoss==null? (OP + staticSL * Instrument.Point): (double) position.StopLoss; double TP = Math.Round(CalculateTP(ExecutionRule.SellStop, OP), Instrument.PriceScale); if (OP >= SL) { SL = OP + staticSL * Instrument.Point; } if (TP >= OP) { TP = (double)Math.Round(OP - 6.28 * Instrument.Spread, Instrument.PriceScale); } do { attempts++; ntR = Trade.UpdatePendingPosition(position.Id, position.Lots, OP, -1, position.ExpireTime, //Bars[_CIndex].Time.AddDays(90.0), SL, TP, "SellStop set OP"); }while ((ntR == null? true: !ntR.IsSuccessful) && attempts < 8); if (ntR == null? true: !ntR.IsSuccessful) { XXPrint("[{2}>>]{1} Cann't modify SellStop order on Price {3} at Bid: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); attempts = 0; do { attempts++; ntR = Trade.CancelPendingPosition(position.Id); }while((ntR == null? true: !ntR.IsSuccessful) && attempts < 8); if (ntR == null? true: !ntR.IsSuccessful) { XXPrint("[*EC*{2}>>]{1} Cann't cancel strange SellStop order on Price {3} at Bid: {0} ", Instrument.Bid, DateTime.Now, Instrument.Name, OP); } else { listOfSellStop.Remove(position.Id); } } else { XXPrint("[{3}>>]{2} Modified successfully SellStop order for position {0} at Price: {1} ", ntR.Position.Id, ntR.Position.OpenPrice, Bars[_CIndex].Time, Instrument.Name); } } }
public override void Read(PacketInput input) { Result = (TradeResult)input.ReadInt32(); Description = input.ReadUTF(); }
protected override void OnTick() { // Put your core logic here if (jTrades == null) { var vol = 1000; TradeResult result = ExecuteMarketOrder(TradeType.Sell, Symbol, vol, label + " : " + "Initial", null, null, null, "Initial"); if (result.IsSuccessful) { // Print("Sell at {0}", result.Position.EntryPrice); jTrades = new JTrade[maxTradesPerSequence]; jTrades[0] = new JTrade(); jTrades[0].profitPips = 30; jTrades[0].hedgePips = -400; jTrades[0].tradeResult = result; jTradesIndex = 0; } } else { //Print("jTrades[" + jTradesIndex + "].tradeResult.Position.Pips = ", jTrades[jTradesIndex].tradeResult.Position.Pips); if (jTrades[jTradesIndex].tradeResult.Position.Pips >= jTrades[jTradesIndex].profitPips) { // Sequence ends profitably: take profits and continue trading // closeSequence(); } else if (jTrades[jTradesIndex].tradeResult.Position.Pips <= jTrades[jTradesIndex].hedgePips) { // Hedging level is reached for the current trade in the sequence: open // a hedging position or close the seqeunce // if (jTradesIndex < maxTradesPerSequence - 1) { // A hedging trade can be opened // jTradesIndex++; var vol = 3000; if (jTradesIndex > 1) { vol = 5000 * (int)Math.Pow(2, jTradesIndex - 2); } TradeType tradeType = TradeType.Buy; if (jTradesIndex % 2 == 0) { tradeType = TradeType.Sell; } TradeResult result = ExecuteMarketOrder(tradeType, Symbol, vol, label + " : " + jTradesIndex, null, null, null, "Trade " + jTradesIndex); if (result.IsSuccessful) { // if (tradeType == TradeType.Buy) // { // Print("Buy at {0}", result.Position.EntryPrice); // } // else // { // Print("Sell at {0}", result.Position.EntryPrice); // } jTrades[jTradesIndex] = new JTrade(); jTrades[jTradesIndex].profitPips = 400; jTrades[jTradesIndex].hedgePips = -400; jTrades[jTradesIndex].tradeResult = result; } } else { // Sequence ends unprofitably: take losses and continue trading // closeSequence(); } } } }
// Set initial StopLoss and TakeProfit private void SetStops(Position position) { double? NewSL = position.StopLoss; double? NewTP = position.TakeProfit; if (StopLoss_Initial > 0 && position.StopLoss == null) { // Manually close position if it's too late to set a SL if (position.Pips <= StopLoss_Initial * (-1)) { ClosePosition(position); return; } if (position.TradeType == TradeType.Buy) NewSL = RND(position.EntryPrice - StopLoss_Initial * symbol.PipSize); else NewSL = RND(position.EntryPrice + StopLoss_Initial * symbol.PipSize); } if (TakeProfit_Initial > 0 && position.TakeProfit == null) { // Manually close position if it's too late to set a TP if (position.Pips >= TakeProfit_Initial) { ClosePosition(position); return; } if (position.TradeType == TradeType.Buy) NewTP = RND(position.EntryPrice + TakeProfit_Initial * symbol.PipSize); else NewTP = RND(position.EntryPrice - TakeProfit_Initial * symbol.PipSize); } result = ModifyPosition(position, NewSL, NewTP); if (!result.IsSuccessful) Print("ERROR: Setting Stops!", result.Error); }