private void ProcessMyOrder(Order MyOrder, Order[] AllOrders, double TotalSpeed) { // Change limit if requested by user. if (MyOrder.SpeedLimit != StartLimit) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Changing limit order #" + MyOrder.ID + " to " + StartLimit.ToString("F2")); MyOrder.SetLimit(StartLimit); } // Check if refill is needed. if (MyOrder.BTCAvailable <= 0.003) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Refilling order #" + MyOrder.ID); if (MyOrder.Refill(0.01)) { MyOrder.BTCAvailable += 0.01; } } // Do not adjust price, if order is dead. if (!MyOrder.Alive) { return; } // Adjust price. double MinimalPrice = GetMinimalNeededPrice(AllOrders, TotalSpeed); if (!IncreasePrice(MyOrder, AllOrders, MinimalPrice)) { DecreasePrice(MyOrder, AllOrders, MinimalPrice); } }
private bool IncreasePrice(Order MyOrder, Order[] AllOrders, double MinimalPrice) { // Do not make price higher if we are already on top of the list (first alive). // Consider fixed orders. foreach (Order O in AllOrders) { if (!O.Alive) { continue; } if (O.OrderType == 1) { continue; } if (O == MyOrder) { return(false); } else { break; } } // Do not increase price, if we already have price higher or equal compared to minimal price. if (MyOrder.Price >= (MinimalPrice - 0.00001)) { return(false); } if (MaxPrice >= MinimalPrice) { // We can set higher price. LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Setting price order #" + MyOrder.ID + " to " + MinimalPrice.ToString("F4")); double NewP = MyOrder.SetPrice(MinimalPrice); if (NewP > 0) { MyOrder.Price = NewP; } return(true); } else if (MyOrder.Price < MaxPrice) { // We can at least set price to be MaxPrice LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Setting price order #" + MyOrder.ID + " to " + MaxPrice.ToString("F4")); double NewP = MyOrder.SetPrice(MaxPrice); if (NewP > 0) { MyOrder.Price = NewP; } return(true); } return(false); }
private void ProcessMyOrder(Order MyOrder, Order[] AllOrders, double TotalSpeed) { double MinimalPrice = GetMinimalNeededPrice(AllOrders, TotalSpeed); // Change limit if requested by user. double __targetSpeed = StartLimit; if (MinimalPrice - MyOrder.Price < APIWrapper.PRICE_DECREASE_STEP[MyOrder.Algorithm] * 5.0) { __targetSpeed = APIWrapper.MINIMAL_LIMIT[MyOrder.Algorithm]; } if (MyOrder.SpeedLimit != __targetSpeed && SpeedTime + APIWrapper.SPEED_CHANGE_INTERVAL < DateTime.Now) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Changing limit order #" + MyOrder.ID + " to " + __targetSpeed.ToString("F2")); MyOrder.SetLimit(__targetSpeed); if (__targetSpeed == APIWrapper.MINIMAL_LIMIT[MyOrder.Algorithm]) { SpeedTime = DateTime.Now; } } // Check if refill is needed. if (MyOrder.BTCAvailable <= 0.001) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Refilling order #" + MyOrder.ID); if (MyOrder.Refill(0.01)) { MyOrder.BTCAvailable += 0.01; } } // Do not adjust price, if order is dead. if (!MyOrder.Alive) { return; } // Adjust price. if (!IncreasePrice(MyOrder, AllOrders, MinimalPrice)) { DecreasePrice(MyOrder, AllOrders, MinimalPrice); } }
/// <summary> /// Initialize API with certain ID and Key. /// </summary> /// <param name="ID">API ID.</param> /// <param name="Key">API Key.</param> /// <returns>True if initialization has succeeded.</returns> public static bool Initialize(string ID, string Key) { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; ValidAuthorization = false; LibConsole.OpenConsole(); LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Initializating API Wrapper with ID=" + ID.ToString() + " and Key=" + Key); LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "This program is compatible with API version " + API_VERSION_COMPATIBLE); APIID = ID; APIKey = Key; // Verify API version string RemoteAPIVersion = GetRemoteAPIVersion(); if (RemoteAPIVersion == null) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.ERROR, "Failed to get API Version."); return(false); } LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Remote API version is " + RemoteAPIVersion); if (RemoteAPIVersion != API_VERSION_COMPATIBLE) { // If API version has changed, only print warning. Program may still work correctly after all. LibConsole.WriteLine(LibConsole.TEXT_TYPE.WARNING, "Service API has changed. This program may not work fully correctly."); } APIBalance Balance = GetBalance(); if (Balance == null) { // If we were unable to get balance, then id and key are incorrect. LibConsole.WriteLine(LibConsole.TEXT_TYPE.ERROR, "Unable to get balance. Are ID and Key correct?"); return(false); } LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Provided ID and Key are correct!"); ValidAuthorization = true; return(true); }
private void DecreasePrice(Order MyOrder, Order[] AllOrders, double MinimalPrice) { // Check time if decrase is possible. if (DecreaseTime + APIWrapper.PRICE_DECREASE_INTERVAL > DateTime.Now) { return; } // Decrease only in case if we are still above or equal to minimal price. Or if we are above maximal price. if (MyOrder.Price + APIWrapper.PRICE_DECREASE_STEP[MyOrder.Algorithm] >= MinimalPrice || MyOrder.Price > MaxPrice) { double NewP = MyOrder.SetPriceDecrease(); if (NewP > 0) { MyOrder.Price = NewP; LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Decreasing price order #" + MyOrder.ID + " to " + NewP.ToString("F4")); DecreaseTime = DateTime.Now; } } }
/// <summary> /// Initialize API with certain ID and Key. /// </summary> /// <param name="ID">API ID.</param> /// <param name="Key">API Key.</param> /// <returns>True if initialization has succeeded.</returns> public static bool Initialize(string ID, string Key) { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; ValidAuthorization = false; LibConsole.OpenConsole(); LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Initializating API Wrapper with ID=" + ID.ToString() + " and Key=" + Key); LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "This program is compatible with API version " + API_VERSION_COMPATIBLE); APIID = ID; APIKey = Key; // Verify API version string RemoteAPIVersion = GetRemoteAPIVersion(); if (RemoteAPIVersion == null) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.ERROR, "Failed to get API Version."); return(false); } LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Remote API version is " + RemoteAPIVersion); if (RemoteAPIVersion != API_VERSION_COMPATIBLE) { // If API version has changed, only print warning. Program may still work correctly after all. LibConsole.WriteLine(LibConsole.TEXT_TYPE.WARNING, "Service API has changed. This program may not work fully correctly."); } APIBalance Balance = GetBalance(); if (Balance == null) { // If we were unable to get balance, then id and key are incorrect. LibConsole.WriteLine(LibConsole.TEXT_TYPE.ERROR, "Unable to get balance. Are ID and Key correct?"); return(false); } LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Provided ID and Key are correct!"); Result <APIBuyInfo> R = Request <Result <APIBuyInfo> >(0, "buy.info", false, null); if (R == null) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.ERROR, "Unable to get buy information. Service unavailable."); return(false); } PRICE_DECREASE_INTERVAL = new TimeSpan(0, 0, R.Data.DownStepTime); ALGORITHM_NAME = new string[R.Data.Algorithms.Length]; PRICE_DECREASE_STEP = new double[R.Data.Algorithms.Length]; ALGORITHM_MULTIPLIER = new double[R.Data.Algorithms.Length]; MINIMAL_LIMIT = new double[R.Data.Algorithms.Length]; SPEED_TEXT = new string[R.Data.Algorithms.Length]; for (int i = 0; i < R.Data.Algorithms.Length; i++) { ALGORITHM_NAME[i] = R.Data.Algorithms[i].Name; PRICE_DECREASE_STEP[i] = R.Data.Algorithms[i].PriceDownStep; ALGORITHM_MULTIPLIER[i] = R.Data.Algorithms[i].Multiplier; MINIMAL_LIMIT[i] = R.Data.Algorithms[i].MinimalLimit; SPEED_TEXT[i] = R.Data.Algorithms[i].SpeedText; } NUMBER_OF_ALGORITHMS = ALGORITHM_NAME.Length; CachedOList = new CachedOrderList[SERVICE_LOCATION.Length, NUMBER_OF_ALGORITHMS]; CachedSList = new CachedStats[SERVICE_LOCATION.Length, NUMBER_OF_ALGORITHMS]; LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Buy information loaded."); ValidAuthorization = true; return(true); }
private static T Request <T>(int?ServiceLocation, string Method, bool AppendCredentials, Dictionary <string, string> Parameters) { string URL = SERVICE_LOCATION + "/api"; if (Method != null) { URL += "?method=" + Method; if (AppendCredentials) { URL += "&id=" + APIID; URL += "&key=" + APIKey; } if (ServiceLocation.HasValue) { // Append location URL += "&location=" + ServiceLocation.ToString(); } if (Parameters != null) { // Append all parameters foreach (KeyValuePair <string, string> Entry in Parameters) { URL += "&" + Entry.Key + "=" + Entry.Value; } } URL = URL.Replace("#", "%23"); } string ResponseData; try { HttpWebRequest WReq = (HttpWebRequest)WebRequest.Create(URL); WReq.Timeout = 60000; WebResponse WResp = WReq.GetResponse(); Stream DataStream = WResp.GetResponseStream(); DataStream.ReadTimeout = 60000; StreamReader SReader = new StreamReader(DataStream); ResponseData = SReader.ReadToEnd(); if (ResponseData[0] != '{') { throw new Exception("Not JSON data."); } } catch (Exception ex) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.ERROR, ex.Message); return(default(T)); } try { // Try to parse with error first, so we see if method failed. Result <APIError> Err = JsonConvert.DeserializeObject <Result <APIError> >(ResponseData); if (Err.Data.Text != null) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.WARNING, "Remote message: '" + Err.Data.Text + "' for request method '" + Method + "'"); return(default(T)); } T Response = JsonConvert.DeserializeObject <T>(ResponseData); return(Response); } catch (Exception ex) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.ERROR, ex.Message); return(default(T)); } }
private bool IncreasePrice(Order MyOrder, Order[] AllOrders, double MinimalPrice) { // Do not make price higher if we are already on top of the list (first alive). // Consider fixed orders. foreach (Order O in AllOrders) { if (!O.Alive) { continue; } if (O.OrderType == 1) { continue; } if (O == MyOrder) { return(false); } else { break; } } // Do not increase price, if we already have price higher or equal compared to minimal price. if (MyOrder.Price >= (MinimalPrice - 0.0001)) { return(false); } // Check time if decrase is possible. if (IncreaseTime + APIWrapper.PRICE_INCREASE_INTERVAL > DateTime.Now) { return(true); } // Определяем границы повышения цены double __newPrice = MaxPrice >= MinimalPrice ? MinimalPrice : MaxPrice; int __steps = (int)Math.Floor((__newPrice - MyOrder.Price) / (APIWrapper.PRICE_DECREASE_STEP[MyOrder.Algorithm] * (-1))); if (__steps > 3 && __steps < 20) { __newPrice = MyOrder.Price - APIWrapper.PRICE_DECREASE_STEP[MyOrder.Algorithm] * 3.0; } if (__newPrice > MyOrder.Price) { LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Setting price order #" + MyOrder.ID + " to " + __newPrice.ToString("F4")); double NewP = MyOrder.SetPrice(__newPrice); if (NewP > 0) { MyOrder.Price = NewP; } IncreaseTime = DateTime.Now; return(true); } return(false); /*if (MaxPrice >= MinimalPrice) * { * // We can set higher price. * LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Setting price order #" + MyOrder.ID + " to " + MinimalPrice.ToString("F4")); * double NewP = MyOrder.SetPrice(MinimalPrice); * if (NewP > 0) MyOrder.Price = NewP; * * return true; * } * else if (MyOrder.Price < MaxPrice) * { * // We can at least set price to be MaxPrice * LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Setting price order #" + MyOrder.ID + " to " + MaxPrice.ToString("F4")); * double NewP = MyOrder.SetPrice(MaxPrice); * if (NewP > 0) MyOrder.Price = NewP; * * return true; * } * * return false; */ }
private void ThreadRun() { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; while (CanRun) { if (!APIWrapper.ValidAuthorization) { System.Threading.Thread.Sleep(500); continue; } lock (this) { bool NewOrder = false; // Verify, if we have order. if (OrderID == 0) { // Need to create order. OrderID = APIWrapper.OrderCreate(ServiceLocation, Algorithm, StartingAmount, StartingPrice, StartLimit, PoolData); if (OrderID > 0) { NewOrder = true; LibConsole.WriteLine(LibConsole.TEXT_TYPE.INFO, "Created new order #" + OrderID.ToString()); } } if (OrderID > 0) { // Get all orders. List <Order> AllOrders = APIWrapper.GetAllOrders(ServiceLocation, Algorithm, NewOrder); if (AllOrders != null) { // Find our order. Order MyOrder = null; foreach (Order O in AllOrders) { if (O.ID == OrderID) { MyOrder = O; break; } } // Get total hashing speed double TS = APIWrapper.GetTotalSpeed(ServiceLocation, Algorithm); if (MyOrder != null) { ProcessMyOrder(MyOrder, AllOrders.ToArray(), TS); LastOrderStats = new Order(MyOrder); } else { // Our order does not exist anymore, create new... OrderID = 0; LastOrderStats = null; } } } } // Wait 30 seconds. for (int i = 0; i < 30; i++) { if (!CanRun) { break; } System.Threading.Thread.Sleep(1000); } } }