private void Arbitrage() { Log.Info("Looking for opportunity..."); var config = _configStore.Config; CheckMaxNetExposure(); SpreadAnalysisResult result; try { result = _spreadAnalyzer.Analyze(_quoteAggregator.Quotes); } catch (Exception ex) { Log.Warn($"Failed to get a spread analysis result. {ex.Message}"); return; } var bestBid = result.BestBid; var bestAsk = result.BestAsk; var invertedSpread = result.InvertedSpread; var availableVolume = result.AvailableVolume; var targetVolume = result.TargetVolume; var targetProfit = result.TargetProfit; Log.Info("{0,-17}: {1}", "Best ask", bestAsk); Log.Info("{0,-17}: {1}", "Best bid", bestBid); Log.Info("{0,-17}: {1}", "Spread", -invertedSpread); Log.Info("{0,-17}: {1}", "Available volume", availableVolume); Log.Info("{0,-17}: {1}", "Target volume", targetVolume); Log.Info("{0,-17}: {1}", "Expected profit", targetProfit); if (invertedSpread <= 0) { Log.Info("No arbitrage opportunity. Spread is not inverted."); return; } Log.Info($"Found inverted quotes."); if (availableVolume < config.MinSize) { Log.Info($"Available volume is smaller than min size. "); return; } if (targetProfit < config.MinTargetProfit) { Log.Info($"Target profit is smaller than min profit."); return; } if (bestBid.Broker == bestAsk.Broker) { Log.Warn($"Ignoring intra-broker cross."); return; } if (config.DemoMode) { Log.Info(">>This is Demo mode. Not sending orders."); return; } Log.Info($">>Found arbitrage oppotunity."); Log.Info($">>Sending order targetting quote {bestAsk}..."); SendOrder(bestAsk, targetVolume, OrderType.Limit); Log.Info($">>Sending order targetting quote {bestBid}..."); SendOrder(bestBid, targetVolume, OrderType.Limit); CheckOrderState(); Log.Info($"Sleeping {config.SleepAfterSend} after send."); _activeOrders.Clear(); Sleep(config.SleepAfterSend); }
private void Arbitrage() { Log.Info(Resources.LookingForOpportunity); var config = _configStore.Config; CheckMaxNetExposure(); SpreadAnalysisResult result; try { result = _spreadAnalyzer.Analyze(_quoteAggregator.Quotes); } catch (Exception ex) { Log.Warn(Resources.FailedToGetASpreadAnalysisResult, ex.Message); return; } var bestBid = result.BestBid; var bestAsk = result.BestAsk; var invertedSpread = result.InvertedSpread; var availableVolume = result.AvailableVolume; var targetVolume = result.TargetVolume; var targetProfit = result.TargetProfit; Log.Info("{0,-17}: {1}", Resources.BestAsk, bestAsk); Log.Info("{0,-17}: {1}", Resources.BestBid, bestBid); Log.Info("{0,-17}: {1}", Resources.Spread, -invertedSpread); Log.Info("{0,-17}: {1}", Resources.AvailableVolume, availableVolume); Log.Info("{0,-17}: {1}", Resources.TargetVolume, targetVolume); Log.Info("{0,-17}: {1}", Resources.ExpectedProfit, targetProfit); if (invertedSpread <= 0) { Log.Info(Resources.NoArbitrageOpportunitySpreadIsNotInverted); return; } Log.Info(Resources.FoundInvertedQuotes); if (availableVolume < config.MinSize) { Log.Info(Resources.AvailableVolumeIsSmallerThanMinSize); return; } if (targetProfit < config.MinTargetProfit) { Log.Info(Resources.TargetProfitIsSmallerThanMinProfit); return; } if (bestBid.Broker == bestAsk.Broker) { Log.Warn($"Ignoring intra-broker cross."); return; } if (config.DemoMode) { Log.Info(Resources.ThisIsDemoModeNotSendingOrders); return; } Log.Info(Resources.FoundArbitrageOppotunity); Log.Info(Resources.SendingOrderTargettingQuote, bestAsk); SendOrder(bestAsk, targetVolume, OrderType.Limit); Log.Info(Resources.SendingOrderTargettingQuote, bestBid); SendOrder(bestBid, targetVolume, OrderType.Limit); CheckOrderState(); Log.Info(Resources.SleepingAfterSend, config.SleepAfterSend); _activeOrders.Clear(); Sleep(config.SleepAfterSend); }