private void startButton_Click(object sender, EventArgs e) { bool errorOccured = false; //Disable inputs while arbitration manager is running DisableInputs(); ArbitrationRun currentRun = new ArbitrationRun(); try { ValidateAndSetInputValues(currentRun); _arbitrationManager.Start(currentRun); } //There was a problem getting the inputs, make the inputs editable again so the user can fix them catch (ArgumentException exception) { errorOccured = true; MessageBox.Show(exception.Message, "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception exception) { errorOccured = true; MessageBox.Show(exception.Message, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (errorOccured) { ResetInputsAfterRunStop(); } }
public bool CompleteTransfersFromPreviousRun(int arbitrationRunId) { //Get arbitration run record from the db: ArbitrationRun previousRun = ArbitrationRun.GetArbitrationRunFromDbById(arbitrationRunId); //Ensure the given was in live mode, as this is to poin to completing transfers from a simulated run if (previousRun.ArbitrationMode == ArbitrationMode.Simulation) { ArbitrationManagerFailureEventHandler handler = ErrorOccured; //Only throw the event is there is a listener if (handler != null) { handler(this, new ArbitrationManagerFailureEventArgs("Arbitration run " + arbitrationRunId + " was ran in simulation mode; no point in completing transfers for it.")); return(false); } } //First need to build up the exchange list, as it is needed by the transfer manager. List <BaseExchange> previousRunExchangeList = BuildExchangeListFromPreviousRun(previousRun); TransferManager.DetectAndExecuteRollupTransfers_Live(1, previousRun.Id.Value, previousRunExchangeList); return(true); }
/// <summary> /// Sets the _exchangeList property of _arbitrationManager to all of the exchanges selected in the form. /// If none of the exchasnge check boxes are checked, an ArgumentException is thrown. /// </summary> private void SetExchangeList(ArbitrationRun run) { foreach (ExchangeCheckBox exchangeCheckBox in _exchangeCheckboxList) { if (exchangeCheckBox.Checked) { run.AddExchange(exchangeCheckBox.ExchangeType); } } //If none of the exchange checkboxes are selected, thrown an error. if (run.ExchangeList.Count <= 0) { throw new ArgumentException(); } }
private List <BaseExchange> BuildExchangeListFromPreviousRun(ArbitrationRun arbitrationRun) { List <BaseExchange> exchangeList = new List <BaseExchange>(); if (arbitrationRun.UseAnx) { exchangeList.Add(new Anx()); } if (arbitrationRun.UseBitfinex) { exchangeList.Add(new Bitfinex()); } if (arbitrationRun.UseBitstamp) { exchangeList.Add(new Bitstamp()); } if (arbitrationRun.UseBitX) { exchangeList.Add(new BitX()); } if (arbitrationRun.UseBtce) { exchangeList.Add(new Btce()); } if (arbitrationRun.UseCoinbase) { exchangeList.Add(new Coinbase()); } if (arbitrationRun.UseItBit) { exchangeList.Add(new ItBit()); } if (arbitrationRun.UseKraken) { exchangeList.Add(new Kraken()); } if (arbitrationRun.UseOkCoin) { exchangeList.Add(new OkCoin()); } return(exchangeList); }
public void Start(ArbitrationRun givenRun) { //Set property because some special logic needs to happen on the set CurrentRun = givenRun; //Now that the run is officially starting, set the start time if it has not already been set //(continued runs keep old start time if (_currentRun.StartDateTime == null) { _currentRun.StartDateTime = DateTime.Now; } //Set the validator _opportunityValidator = new OpportunityValidator(givenRun.RoundsRequiredForValidation, CurrentRun.ExchangeList); //Need to reset previousOpportunity since this is a new run; don't validate opportunities from previous runs _previousOpportunity = null; try { _currentRun.PersistToDb(); log.Info("Arbitration hunting started. Arbitration run ID = " + givenRun.Id + "."); SetExchangeTradeFee(); SetInitialAccountBalances(); DisplayExchangeBalances(); _timer.Interval = _currentRun.SeachIntervalMilliseconds; _timer.Enabled = true; _stopped = false; } //Catch any kind of exception here that could occur from updating the exchange balances. A problem can manifest itself several ways depending on the exchange, so this needs to be a catch all. catch (Exception exception) { OnError("There was a problem updating one of the exchange balances.", exception, "There was a problem getting the account balance for one of the exchanges: "); } }
/// <summary> /// Validates all the inputs of the form. If the input is validated, it is passed on to the given arbitration run. If any of the /// fields weren't valid, an ArgumentException is thrown. If this method is called and the input field is empty, the default value /// of that input is used. The log file input is an exception to this; if that is null then the given run just doesn't have a log file. /// </summary> /// <param name="Run">The arbitration run the parameters are added to if everything is valid.</param> private void ValidateAndSetInputValues(ArbitrationRun Run) { int searchInterval; int roundsRequiredForValidation; decimal maxBtcTradeAmount; decimal minimumProfit; decimal maxFiatTradeAmount; decimal? percentageRestriction = null; int? rollupNumber = null; decimal? rollupHours = null; StringBuilder errorMessage = new StringBuilder(""); //Get the config settings from app.config NameValueCollection inputSettings = (NameValueCollection)ConfigurationManager.GetSection(INPUT_SETTINGS_PATH); //Get Fiat Type try { Run.FiatType = (FiatType)Enum.Parse(typeof(FiatType), inputSettings["FiatType"]); } catch (Exception) { AppendToErrorMessage(errorMessage, "Fiat Type is not valid."); } //Validate Minimum profit if (!String.IsNullOrWhiteSpace(txbMinProfit.Text)) { minimumProfit = ParseAndValidateInputDecimal(txbMinProfit.Text, lblMinProfit.Text, ref errorMessage); } else { txbMinProfit.Text = "" + defaultMinProfitForTrade; minimumProfit = defaultMinProfitForTrade; } //Validate search interval if (!String.IsNullOrWhiteSpace(txbSearchInterval.Text)) { searchInterval = ParseAndValidateInputInteger(txbSearchInterval.Text, lblSearchInterval.Text, ref errorMessage); //Search interval was a valid number; convert it from seconds to milliseconds searchInterval = searchInterval * 1000; } else { //Convert the search interval to seconds and display it txbSearchInterval.Text = "" + defaultSearchInterval / 1000; searchInterval = defaultSearchInterval; } //Validate rounds required for validation if (!String.IsNullOrWhiteSpace(txbRoundsRequiredForValidation.Text)) { roundsRequiredForValidation = ParseAndValidateInputInteger(txbRoundsRequiredForValidation.Text, lblRoundsRequiredForValidation.Text, ref errorMessage); } else { //Convert the search interval to seconds and display it txbRoundsRequiredForValidation.Text = "" + defaultRoundsRequiredForValidation; roundsRequiredForValidation = defaultRoundsRequiredForValidation; } //Validate max BTC amount if (!String.IsNullOrWhiteSpace(txbMaxBtcTradeAmount.Text)) { maxBtcTradeAmount = ParseAndValidateInputDecimal(txbMaxBtcTradeAmount.Text, lblMaxBtcLabel.Text, ref errorMessage); } else { txbMaxBtcTradeAmount.Text = "" + defaultMaxBtcTradeAmount; maxBtcTradeAmount = defaultMaxBtcTradeAmount; } //Validate max Fiat amount if (!String.IsNullOrWhiteSpace(txbMaxFiatTradeAmount.Text)) { maxFiatTradeAmount = ParseAndValidateInputDecimal(txbMaxFiatTradeAmount.Text, lblMaxFiatLabel.Text, ref errorMessage); } else { txbMaxFiatTradeAmount.Text = "" + defaultMaxFiatTradeAmount; maxFiatTradeAmount = defaultMaxFiatTradeAmount; } //Validate percentage restriction if (rbMostProfitableWithPercentRestriction.Checked) { percentageRestriction = ParseAndValidateInputInteger(txbRestrictionPercent.Text, lblPercentRestriction.Text, ref errorMessage); } //Validate rollup trade number if (rbTransferModeRollupOnTrades.Checked) { rollupNumber = ParseAndValidateInputInteger(txbRollupNumber.Text, lblRollupNumber.Text, ref errorMessage); } //Validate rollup hours if (rbTransferModeRollupByHours.Checked) { rollupHours = ParseAndValidateInputDecimal(txbRollupHours.Text, lblRollupHours.Text, ref errorMessage); } //Validate log file if (!String.IsNullOrWhiteSpace(txbLogFileName.Text)) { try { Run.LogFileName = txbLogFileName.Text; } catch (IOException) { AppendToErrorMessage(errorMessage, "The specified log file cannot be used."); } } else { Run.LogFileName = null; } try { //Get exchange list from user and pass it to arbitration manager SetExchangeList(Run); } catch (ArgumentException) { AppendToErrorMessage(errorMessage, "Please select at least one exchange."); } //If there was an validation error, throw an error if (errorMessage.Length > 0) { throw new ArgumentException(errorMessage.ToString()); } //If the code made it this far, all inputs are valid, so update the current run with the inputs Run.MinimumProfit = minimumProfit; Run.SeachIntervalMilliseconds = searchInterval; Run.RoundsRequiredForValidation = roundsRequiredForValidation; Run.MaxBtcTradeAmount = maxBtcTradeAmount; Run.MaxFiatTradeAmount = maxFiatTradeAmount; Run.OpportunitySelectionMethod = GetCheckedOpportunitySelectionRadioButton().SelectionType; Run.ExchangeBaseCurrencyPercentageRestriction = percentageRestriction / 100; Run.TransferMode = GetCheckedTransferModeRadioButton().TransferMode; Run.RollupNumber = rollupNumber; Run.RollupHours = rollupHours; Run.ArbitrationMode = GetCheckedArbitrationModeRadioButton().ArbitrationMode; }
private void SetInputsForContinuedRun(ArbitrationRun continuedRun) { try { //Now set all the inputs switch (continuedRun.ArbitrationMode) { case ArbitrationMode.Simulation: rbSimulation.Checked = true; break; case ArbitrationMode.Live: rbLive.Checked = true; break; default: throw new Exception("Given run has unknown arbitration mode"); } switch (continuedRun.TransferMode) { case TransferMode.OnTime: case TransferMode.RollupByHour: case TransferMode.RollupOnTrades: throw new Exception("Cannot continue the given arbitration run; it uses a transfer mode that is not supported"); case TransferMode.None: rbTransferModeNone.Checked = true; break; default: throw new Exception("Given run has unknown transfer mode"); } switch (continuedRun.OpportunitySelectionMethod) { case OpportunitySelectionType.MostProfitableOpportunity: rbMostProfitable.Checked = true; break; case OpportunitySelectionType.OpportunityForExchangeWithLeastBtc: rbExchangeWithLeastBtc.Checked = true; break; case OpportunitySelectionType.MostProfitableWithPercentRestriction: rbMostProfitableWithPercentRestriction.Checked = true; txbRestrictionPercent.Text = continuedRun.ExchangeBaseCurrencyPercentageRestriction.ToString(); break; } chxAnx.Checked = continuedRun.UseAnx; chxBitfinex.Checked = continuedRun.UseBitfinex; chxBitstamp.Checked = continuedRun.UseBitstamp; chxBitX.Checked = continuedRun.UseBitX; chxBtce.Checked = continuedRun.UseBtce; chxItBit.Checked = continuedRun.UseItBit; chxKraken.Checked = continuedRun.UseKraken; chxOkCoin.Checked = continuedRun.UseOkCoin; chxCoinbase.Checked = continuedRun.UseCoinbase; txbMinProfit.Text = continuedRun.MinimumProfit.ToString(); txbRoundsRequiredForValidation.Text = continuedRun.RoundsRequiredForValidation.ToString(); txbMaxBtcTradeAmount.Text = continuedRun.MaxBtcTradeAmount.ToString(); txbMaxFiatTradeAmount.Text = continuedRun.MaxFiatTradeAmount.ToString(); txbSearchInterval.Text = (continuedRun.SeachIntervalMilliseconds / 1000).ToString(); txbLogFileName.Text = ""; } catch (Exception) { throw; } }
public static ArbitrationRun GetArbitrationRunFromDbById(int arbitrationRunId) { DataTable results = DatabaseManager.ExecuteQuery("SELECT * from ARBITRATION_RUN where ID = " + arbitrationRunId); ArbitrationRun returnRun = null; if (results != null) { returnRun = new ArbitrationRun(); returnRun.Id = (int)results.Rows[0]["ID"]; returnRun.UseAnx = (bool)results.Rows[0]["USE_ANX"]; returnRun.UseBitfinex = (bool)results.Rows[0]["USE_BITFINEX"]; returnRun.UseBitstamp = (bool)results.Rows[0]["USE_BITSTAMP"]; returnRun.UseBitX = (bool)results.Rows[0]["USE_BITX"]; returnRun.UseBtce = (bool)results.Rows[0]["USE_BTCE"]; returnRun.UseCoinbase = (bool)results.Rows[0]["USE_COINBASE"]; returnRun.UseItBit = (bool)results.Rows[0]["USE_ITBIT"]; returnRun.UseKraken = (bool)results.Rows[0]["USE_KRAKEN"]; returnRun.UseOkCoin = (bool)results.Rows[0]["USE_OKCOIN"]; returnRun.MinimumProfit = Convert.ToDecimal(results.Rows[0]["MINIMUM_PROFIT_FOR_TRADE"]); returnRun.SeachIntervalMilliseconds = Convert.ToInt16(results.Rows[0]["SEARCH_INTERVAL_MILLISECONDS"]); returnRun.RoundsRequiredForValidation = Convert.ToInt16(results.Rows[0]["ROUNDS_REQUIRED_FOR_VALIDATION"]); returnRun.MaxBtcTradeAmount = Convert.ToDecimal(results.Rows[0]["MAX_BTC_FOR_TRADE"]); returnRun.MaxFiatTradeAmount = Convert.ToDecimal(results.Rows[0]["MAX_FIAT_FOR_TRADE"]); returnRun.FiatType = (FiatType)Enum.Parse(typeof(FiatType), (string)results.Rows[0]["FIAT_TYPE"]); returnRun.OpportunitySelectionMethod = (OpportunitySelectionType)Enum.Parse(typeof(OpportunitySelectionType), (string)results.Rows[0]["OPPORTUNITY_SELECTION_METHOD"]); if (results.Rows[0]["EXCHANGE_BASE_CURRENCY_PERCENTAGE_RESTRICTION"] == DBNull.Value) { returnRun.ExchangeBaseCurrencyPercentageRestriction = null; } else { returnRun.ExchangeBaseCurrencyPercentageRestriction = Convert.ToDecimal(results.Rows[0]["EXCHANGE_BASE_CURRENCY_PERCENTAGE_RESTRICTION"]); } returnRun.LogFileName = (string)results.Rows[0]["LOG_FILE"]; returnRun.ArbitrationMode = (ArbitrationMode)Enum.Parse(typeof(ArbitrationMode), (string)results.Rows[0]["MODE"]); returnRun.TransferMode = (TransferMode)Enum.Parse(typeof(TransferMode), (string)results.Rows[0]["TRANSFER_MODE"]); if (results.Rows[0]["ROLLUP_TRADE_NUMBER"] == DBNull.Value) { returnRun.RollupNumber = null; } else { returnRun.RollupNumber = Convert.ToInt16(results.Rows[0]["ROLLUP_TRADE_NUMBER"]); } if (results.Rows[0]["ROLLUP_HOURS"] == DBNull.Value) { returnRun.RollupHours = null; } else { returnRun.RollupHours = Convert.ToInt16(results.Rows[0]["ROLLUP_HOURS"]); } returnRun.StartDateTime = (DateTime?)results.Rows[0]["START_DATETIME"]; returnRun.EndDateTime = (DateTime?)results.Rows[0]["END_DATETIME"]; returnRun.CreateDateTime = (DateTime?)results.Rows[0]["CREATE_DATETIME"]; returnRun.LastModifiedDateTime = (DateTime?)results.Rows[0]["LAST_MODIFIED_DATETIME"]; } return(returnRun); }