private ExchangeOrderRequest GetExchangeOrderRequest(bool isBuyOrder, IExchangeAPI api) { var exchangeOrderRequest = new ExchangeOrderRequest { Amount = Amount, Price = Price, IsBuy = isBuyOrder, IsMargin = IsMargin, MarketSymbol = api.NormalizeMarketSymbol(MarketSymbol), OrderType = OrderType, StopPrice = StopPrice, ShouldRoundAmount = ShouldRoundAmount }; Amount = exchangeOrderRequest.RoundAmount(); return(exchangeOrderRequest); }
public void TestGdaxOrder() { var order = new ExchangeOrderRequest(); order.OrderType = OrderType.Limit; order.Symbol = "ETH-USD"; order.Price = 390.19M; order.Amount = 0.1M; order.IsBuy = true; //order.ShouldRoundAmount = true; //order.RoundAmount(); //var parameters = order.ExtraParameters; order.ExtraParameters["post_only"] = true; //var api = new ExchangeGdaxAPI(); //api.LoadAPIKeysUnsecure(m_creds["GDAX"].Key, m_creds["GDAX"].Secret, m_creds["GDAX"].Passphrase); //var api = m_apiMap["GDAX"]; m_api.gdax.PlaceOrder(order); }
public static ExchangeOrderResult Order(ExchangeOrderRequest order) { ExchangeOrderResult orderMarket = new ExchangeOrderResult(); try { orderMarket = StaticVariables.api.PlaceOrder(order); } catch (Exception ex) { DateTime localDate = DateTime.Now; string printResult = String.Format("{0}\n{1}\n{2}", localDate.ToString(), order.ToString(), ex.ToString()); string fileName = String.Format("{0}_{1}_{2}", MethodBase.GetCurrentMethod().Name, StaticVariables.api.Name, (order.IsBuy ? "Buy" : "Sell")); PrintException.Start_2(fileName, ex, printResult); throw ex; } return(orderMarket); }
protected override async Task <TypedActionHandlerResult <ExchangeOrderResult> > Execute(Dictionary <string, object> data, RecipeAction recipeAction, PlaceOrderData actionData) { var externalService = await recipeAction.GetExternalService(); var exchangeService = new ExchangeService(externalService); var client = exchangeService.ConstructClient(); var orderRequest = new ExchangeOrderRequest() { MarketSymbol = actionData.MarketSymbol, OrderType = actionData.OrderType, Price = Convert.ToDecimal(InterpolateString(actionData.Price, data)), Amount = Convert.ToDecimal(InterpolateString(actionData.Amount, data)), StopPrice = Convert.ToDecimal(InterpolateString(actionData.StopPrice, data)), IsBuy = actionData.IsBuy, IsMargin = actionData.IsMargin, ShouldRoundAmount = false }; try { var result = await client.PlaceOrderAsync(orderRequest); System.Threading.Thread.Sleep(500); result = await client.GetOrderDetailsAsync(result.OrderId); return(new TypedActionHandlerResult <ExchangeOrderResult>() { Executed = true, Result = $"Place order ({result.OrderId}) Status: {result.Result}", TypedData = result }); } catch (Exception e) { return(new TypedActionHandlerResult <ExchangeOrderResult>() { Executed = false, Result = $"Could not place order because {e.Message}. Order details: {JsonConvert.SerializeObject(orderRequest)}" }); } }
private ExchangeOrderResult ParsePlaceOrder(JToken token, ExchangeOrderRequest order) { /* * {"result":true,"order_id":123456} */ ExchangeOrderResult result = new ExchangeOrderResult { Amount = order.Amount, Price = order.Price, IsBuy = order.IsBuy, OrderId = token["order_id"].ToStringInvariant(), MarketSymbol = order.MarketSymbol }; result.AveragePrice = result.Price; result.Result = ExchangeAPIOrderResult.Open; return(result); }
// where symbol like "ETH-USD" // where side is OrderSide.Buy/OrderSide.Sell // where price like 390.19M // where amount like 0.1M // where postOnly is true/false (true means DO NOT allow "taker" -- "maker" only) public static ExchangeOrderResult GdaxOrder(ExchangeGdaxAPI api, string symbol, OrderSide side, decimal price, decimal amount, bool postOnly = true) { var order = new ExchangeOrderRequest(); order.OrderType = OrderType.Limit; order.Symbol = symbol; order.Price = price; order.Amount = amount; order.IsBuy = side == OrderSide.Buy; //order.ShouldRoundAmount = true; //order.RoundAmount(); //var parameters = order.ExtraParameters; order.ExtraParameters["post_only"] = postOnly; //var api = new ExchangeGdaxAPI(); //api.LoadAPIKeysUnsecure(m_creds["GDAX"].Key, m_creds["GDAX"].Secret, m_creds["GDAX"].Passphrase); //var api = m_apiMap["GDAX"]; return(api.PlaceOrder(order)); }
protected override async Task <ActionHandlerResult> Execute(object triggerData, RecipeAction recipeAction, PlaceOrderData actionData) { var exchangeService = new ExchangeService(recipeAction.ExternalService); var client = exchangeService.ConstructClient(); var orderRequest = new ExchangeOrderRequest() { OrderType = actionData.OrderType, Price = Convert.ToDecimal(InterpolateString(actionData.Price, triggerData)), Amount = Convert.ToDecimal(InterpolateString(actionData.Amount, triggerData)), StopPrice = Convert.ToDecimal(InterpolateString(actionData.StopPrice, triggerData)), IsBuy = actionData.IsBuy, IsMargin = actionData.IsMargin, }; try { var result = await client.PlaceOrderAsync(orderRequest); System.Threading.Thread.Sleep(500); result = await client.GetOrderDetailsAsync(result.OrderId); return(new ActionHandlerResult() { Executed = true, Result = $"Place order ({result.OrderId}) Status: {result.Result}" }); } catch (Exception e) { return(new ActionHandlerResult() { Executed = false, Result = $"Could not place order because {e.Message}" }); } }
public async Task <string> Sell(string market, decimal quantity, decimal rate) { var request = new ExchangeOrderRequest() { Amount = quantity, IsBuy = false, OrderType = ExchangeSharp.OrderType.Limit, Price = rate, Symbol = market }; try { var order = await _api.PlaceOrderAsync(request); return(order.OrderId); } catch (Exception ex) { Global.Logger.Error(ex, $"Error on PlaceOrderAsync"); } return(null); }
public async void doBuy(Asset asset) { try { bool isSuccess = false; if (this.isLiveTrading) { decimal cashAvail = 0; // check to see if we have enough cash. if (myWallet.ContainsKey(QUOTECURRENCY)) { cashAvail = myWallet[QUOTECURRENCY]; } var coinsHeld = this.Assets.Where(a => a.HasTrade).Count(); if (coinsHeld >= maxCoins) { throw new Exception($"Insufficient funds to buy {asset.Ticker}. CoinsHeld exceeded. {coinsHeld}"); } // get the number of shares to buy. var shares = RoundShares.GetRoundedShares(stakeSize, asset.Price); if (shares < 0.01m) { throw new Exception($"${shares} is too small for {asset.Ticker}."); } var order = new ExchangeOrderRequest { Amount = shares, IsBuy = true, Price = asset.Ask, MarketSymbol = asset.Ticker, OrderType = OrderType.Market }; var result = await api.PlaceOrderAsync(order); logger.Trace($"TRY BUY, {result.MarketSymbol}, {result.Price}, {result.Result}, {result.OrderId}"); if (result.Result != ExchangeAPIOrderResult.Error) { isSuccess = true; // manually reduce the walletsize. it will be for real once every 15 minutes. myWallet[QUOTECURRENCY] = cashAvail - stakeSize; } } if (isSuccess || !isLiveTrading) { asset.HasTrade = true; asset.BuyPrice = asset.Ask; asset.MaxPrice = asset.BuyPrice; asset.LastBuyTime = DateTime.UtcNow; asset.StopLoss = 0; // disable stoploss. logger.Info($"Buy, {asset.Ticker}, BuyPrice: {asset.BuyPrice}, StopLoss: {asset.StopLoss}"); } } catch (Exception ex) { logger.Info($"Buy - ERROR, {asset.Ticker}"); logger.Trace($"Buy {asset.Ticker} failed with {ex.Message}"); } }
public static bool HandlingOneOrderTrade(OrderHandling orderHandling, bool firstOrder) { orderHandling.OrderToCare.StartTrade(); orderHandling.OrderToCare.Result = TradeUseCase.Order(orderHandling.OrderToCare.Request); string resPrint = String.Format("Handling Order - {0}-{1}, ExtraPercent {2:P0}, Percentage(without ExtraPercent) - {3:P3}, realPercentage - {4:P3}", (orderHandling.OrderToCare.request.IsBuy ? "Buy" :"Sell"), orderHandling.OrderToCare.request.Symbol, orderHandling.OrderToCare.extraPercent.Percent, orderHandling.percent / 100, orderHandling.realPercentage / 100); PrintTable.PrintConsole(resPrint); int useCase = 0; decimal difPrecentge = 0; System.Threading.Thread.Sleep(orderHandling.OrderToCare.ExtraPercent.WaitingTimeForNextPriceUpdate); orderHandling.OrderToCare.Result = TradeUseCase.OrderDetails(orderHandling.OrderToCare.Result); DateTime startTimeSmallAmount = DateTime.Now; while (!orderHandling.OrderToCare.Done) { if (orderHandling.OrderToCare.itsCanAdded & orderHandling.OrderToCare.itsCanUpdate) { startTimeSmallAmount = DateTime.Now; if (orderHandling.OrderToCare.Result.Result == ExchangeAPIOrderResult.FilledPartially) { difPrecentge = orderHandling.OrderToCare.Result.AmountFilled / orderHandling.OrderToCare.Result.Amount; if (difPrecentge > 0.99m) { useCase = 4; // Current Order Cancellation } else { useCase = 3; // We will also update the price in addition to the quantity update } } else // if (orderHandling.OrderToCare.Result.Result == ExchangeAPIOrderResult.Pending) { useCase = 1; // Update price } TradeUseCase.Start(useCase, orderHandling); } else if (orderHandling.OrderToCare.Result.Result == ExchangeAPIOrderResult.Filled) { return(true); } else if (orderHandling.OrderToCare.Result.Result == ExchangeAPIOrderResult.FilledPartially) { if (firstOrder) // We will cancel an order only in the case of a first order, because in other orders we will want the order to remain until it is executed { DateTime timeSmallAmount = DateTime.Now; if (!(timeSmallAmount.Subtract(startTimeSmallAmount).TotalMinutes > 1)) // Limit of waiting for order to 1 minute { if ((orderHandling.OrderToCare.Result.AmountFilled + orderHandling.OrderToCare.AmountFilledDifferentOrderNumber) < orderHandling.minAmountTrade) // try fix bug of buying a small amount of coins, In use case of the quantity is less than the minimum for the trade, we will continue to wait until at least the required minimum is filled { continue; } } else { useCase = 4; // Current Order Cancellation TradeUseCase.Start(useCase, orderHandling); if (orderHandling.OrderToCare.amountFilled < orderHandling.minAmountTrade) // try fix bug of buying a small amount of coins, In use case of the quantity is less than the minimum for the trade, we will continue to wait until at least the required minimum is filled { ExchangeOrderRequest revertOrder = new ExchangeOrderRequest(); try { revertOrder.Amount = orderHandling.OrderToCare.amountFilled; revertOrder.IsBuy = false; revertOrder.OrderType = StaticVariables.orderType; revertOrder.Price = orderHandling.OrderToCare.Request.Price * (1 + (StaticVariables.FeeTrade * 2)); revertOrder.Symbol = orderHandling.OrderToCare.Request.Symbol; OrderTrade revertOrderTrade = new OrderTrade(revertOrder); revertOrderTrade.Result = StaticVariables.api.PlaceOrder(revertOrder); PrintTable.Start(StaticVariables.pathWithDate + "Small_Amount_Handling.csv", orderHandling.OrderToCare.Result.PrintSymbol(), "OrderResultSymbol"); PrintTable.Start(StaticVariables.pathWithDate + "Small_Amount_Handling.csv", revertOrderTrade.Result.PrintSymbol(), "OrderResultSymbol"); } catch (Exception ex) { StaticVariables.Wallet = WalletFunc.GetWallet(); // Wallet update. Because part of the trade was carried out. Apparently the amounts of coins have changed string warningMessage = String.Format("{0},\tamountFilled - {1},\tAmount - {2},\tminAmountTrade - {3},", orderHandling.OrderToCare.request.Symbol, orderHandling.OrderToCare.amountFilled, orderHandling.OrderToCare.request.Amount, orderHandling.minAmountTrade); PrintTable.PrintConsole(warningMessage); PrintFunc.AddLine(StaticVariables.pathWithDate + "Small_Amount_Left.txt", warningMessage); PrintTable.Start(StaticVariables.pathWithDate + "Small_Amount_Left.csv", orderHandling.OrderToCare.request.Print(), "OrderResult"); DateTime localDate = DateTime.Now; string printResult = String.Format("{0}\n{1}", localDate.ToString(), ex.ToString()); PrintException.Start("Small_Amount_Left", printResult); } } return(orderHandling.OrderToCare.succsseFirstOrder); } } else { orderHandling.OrderToCare.ItsOrderLeft = true; return(false); } } else if (orderHandling.OrderToCare.Result.Result == ExchangeAPIOrderResult.Pending) { if (firstOrder) // We will cancel an order only in the case of a first order, because in other orders we will want the order to remain until it is executed { useCase = 4; // Current Order Cancellation TradeUseCase.Start(useCase, orderHandling); return(orderHandling.OrderToCare.succsseFirstOrder); } else { orderHandling.OrderToCare.ItsOrderLeft = true; return(false); } } if (!orderHandling.OrderToCare.Done) { System.Threading.Thread.Sleep(orderHandling.OrderToCare.ExtraPercent.WaitingTimeForNextPriceUpdate); orderHandling.OrderToCare.Result = TradeUseCase.OrderDetails(orderHandling.OrderToCare.Result); if (orderHandling.OrderToCare.Result.Result == ExchangeAPIOrderResult.Canceled) // In case a cancellation was made by the stock exchange due to an order or quantity error { bool checkCancel = CancellationFunc.ReviewCancellationAndUpdateOrder(orderHandling); if (firstOrder) { return(orderHandling.OrderToCare.succsseFirstOrder); } else { // TODO Check what amount has not traded. Maybe by the wallet. Update amount and send request in the current function } } } } if (firstOrder) { return(orderHandling.OrderToCare.succsseFirstOrder); // amountFilled > minAmaunt } else { return(orderHandling.OrderToCare.succsseTrade); // ((amountFilled == amountStart) || (amountFilled >= amountFinish)) } }
private Task DoBuy(bool isBuy, Input input) { try { var marketid = $"{input.TargetCurrency}{input.BaseCurrency}"; var baseCurrency = input.BaseCurrency; var targetCurrency = input.TargetCurrency; //var initalPrice = input.InitalPrice; var depth = input.ExchangeApi.GetOrderBook(marketid, 10); var txPrice = input.InitalPrice == 0 ? (isBuy ? depth.Asks.OrderBy(a => a.Value.Price).FirstOrDefault() : depth.Bids.OrderByDescending(a => a.Value.Price).FirstOrDefault()).Value.Price : input.InitalPrice; //获取账户信息,确定目前账户存在多少钱和多少币 var account = input.ExchangeApi.GetAmountsAvailableToTrade(); var order = new ExchangeOrderRequest(); if (isBuy) { //可买的比特币量 var amountTx = account.TryGetValueOrDefault(baseCurrency, 0) / txPrice; if (amountTx < 0.001m) { return(Task.CompletedTask); } order.Amount = SelfMath.ToFixed(amountTx * decimal.Parse(input.Hold) / 100, int.Parse(input.Precision)); order.IsBuy = isBuy; order.Price = txPrice; order.Symbol = marketid; input.ExchangeApi.PlaceOrder(order); input.InitalPrice = order.Price; input.Amount = order.Amount.ToString(); input.Status = InputStatus.Doing; } else { var rangePriceMin = input.InitalPrice * (1 + decimal.Parse(input.GainPointMin) / 100); //var rangePriceMax = holdPrice * (1 + decimal.Parse(TxtRangeMax.Text.Trim())); var lossPrice = input.InitalPrice * (1 - decimal.Parse(input.LossPoint) / 100); input.SellPrice = txPrice; if ((txPrice >= rangePriceMin) || (txPrice <= lossPrice)) { order.Amount = SelfMath.ToFixed(decimal.Parse(input.Amount) * (1 - 2.5m / 1000), int.Parse(input.Precision)); order.IsBuy = isBuy; order.Price = txPrice; order.Symbol = marketid; input.ExchangeApi.PlaceOrder(order); input.Status = InputStatus.Done; } } } catch (Exception e) { using (FileStream fs = new FileStream("log.txt", FileMode.Append)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.WriteLine(e.Message.ToString() + "/r/n"); } } } return(Task.CompletedTask); }
public static decimal GetPrice(ExchangeOrderBook book, SymbolsDate item, bool buy) { decimal price = 0; decimal amaunt = 0; int j = 0; do { if (buy) { if (book.Asks.Count <= j) { return(0); } price = book.Asks[j].Price; amaunt = book.Asks[j].Amount; } else { if (book.Bids.Count <= j) { return(0); } price = book.Bids[j].Price; amaunt = book.Bids[j].Amount; } j++; if (j == StaticVariables.maxCount) // In case the first 5 orders in the bookOrder are below the minimum required quantity { StaticVariables.maxCount = 10; return(0); } if (!buy) { item.MinAmount = price; } } while (amaunt < item.MinAmount); ExchangeOrderRequest request = new ExchangeOrderRequest(); request.Amount = amaunt; request.IsBuy = buy; request.OrderType = StaticVariables.orderType; request.Price = price; request.Symbol = item.symbole; OrderTrade orderTrade = new OrderTrade(request); if (buy) { item.buyOrderTrade = orderTrade; } else { item.sellOrderTrade = orderTrade; } price = WalletFunc.ConversionPrice(price, item.payment); #if DEBUG FindDebug += String.Format("{0}\tSymbol - {1}\n", (request.IsBuy ? "Buy" : "Sell"), request.Symbol); FindDebug += String.Format("while (amaunt < item.MinAmount) count - {0}\n", j); FindDebug += String.Format("MinAmount - {0}\n", item.MinAmount); FindDebug += String.Format("request - {0}\n", request.Print()); FindDebug += String.Format("price - {0}\n\n", price); #endif return(price); }
public static ExchangeUpdateOrder UpdateOrder(ExchangeOrderResult orderCancel, ExchangeOrderRequest orderNew) { ExchangeUpdateOrder orderUpdate = new ExchangeUpdateOrder(); try { orderUpdate = StaticVariables.api.UpdateOrder(orderCancel, orderNew); } catch (Exception ex) { DateTime localDate = DateTime.Now; string printResult = String.Format("{0}\norderCancel - {1}\norderNew - {2}\n{3}", localDate.ToString(), orderCancel.ToString(), orderNew.ToString(), ex.ToString()); string fileName = String.Format("{0}_{1}_{2}", MethodBase.GetCurrentMethod().Name, StaticVariables.api.Name, (orderNew.IsBuy ? "Buy" : "Sell")); PrintException.Start_2(fileName, ex, printResult); throw ex; } return(orderUpdate); }