private RobotFarm() { configFilePath = ExecutablePath.ExecPath + "\\farmsets.xml"; timerThread = new Thread(TimerThreadFunction); portfolioTradeSettings = new AutoTradeSettings(); packerPool = new CandlePackerPool(); }
/// <summary> /// подписать на портфель /// отключить остальные подписки /// если портфель пользовательский - сохранить его /// </summary> public RequestStatus SubscribeOnPortfolio( ProtectedOperationContext secCtx, string subscriberLogin, TopPortfolio portfolio, decimal?maxFee, AutoTradeSettings tradeAutoSettings) { //Logger.InfoFormat("SubscribeOnPortfolio({0})", subscriberLogin); if (UserOperationRightsStorage.IsProtectedOperation(UserOperation.BindToSignal)) { if (!UserSessionStorage.Instance.PermitUserOperation(secCtx, UserOperationRightsStorage.IsTradeOperation(UserOperation.BindToSignal), false)) { return(RequestStatus.Unauthorized); } } try { using (var ctx = DatabaseContext.Instance.Make()) return(walletRepository.SubscribeUserOnPortfolio(ctx, subscriberLogin, portfolio, maxFee, tradeAutoSettings)); } catch (Exception ex) { Logger.Error("Ошибка в SubscribeOnPortfolio()", ex); return(RequestStatus.ServerError); } }
private void Subscribe(object sender, EventArgs e) { RequestStatus status; try { if (isSubsribed) { status = AccountModel.Instance.ServerProxy.UnsubscribePortfolio( CurrentProtectedContext.Instance.MakeProtectedContext(), AccountModel.Instance.GetUserLogin(), true, true); } else { var complete = new CompleteSubscribeOnPortfolioDlg(portfolio).ShowDialog() == DialogResult.OK; if (!complete) { return; } var tradeSettings = new AutoTradeSettings(); // открыть диалог настройки авто-торговли var dlg = new AutoTradeSettingsForm(); if (dlg.ShowDialog(this) == DialogResult.OK) { tradeSettings = dlg.sets; } status = AccountModel.Instance.ServerProxy.SubscribeOnPortfolio( CurrentProtectedContext.Instance.MakeProtectedContext(), AccountModel.Instance.GetUserLogin(), portfolio, null, tradeSettings); } } catch (Exception ex) { //4 debug MessageBox.Show(this, "Операция выполнена с ошибкой:" + Environment.NewLine + ex.Message, Localizer.GetString("TitleWarning"), MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Logger.Info("TopPortfolioControl.Subscribe: error calling SubscribeOnPortfolio/UnsubscribePortfolio", ex); return; } if (status == RequestStatus.OK) { MessageBox.Show(this, "Операция выполнена успешно", Localizer.GetString("TitleInformation"), MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(this, "Операция выполнена с ошибкой:" + Environment.NewLine + EnumFriendlyName <RequestStatus> .GetString(status), Localizer.GetString("TitleWarning"), MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } IsSubsribed = !isSubsribed; if (SubscriptionChanged != null) { SubscriptionChanged(this, new EventArgs()); } }
public RequestStatus SubscribeOnPortfolio(string hash, string userLogin, long localTime, int portfolioId, AutoTradeSettings tradeAutoSettings) { var portfolio = new TopPortfolio { Id = portfolioId }; return(SubscribeOnUserOrCustomPortfolio(hash, userLogin, localTime, portfolio, tradeAutoSettings)); }
private void TradeSettingsButtonOkClicked() { var controlSets = tradeSettings.DataContext; if (controlSets == null) { return; } sets = controlSets; DialogResult = DialogResult.OK; Close(); }
public RequestStatus SubscribeOnCustomPortfolio(string hash, string userLogin, long localTime, string formula, float?marginValue, int topCount, AutoTradeSettings tradeAutoSettings) { var portfolio = new TopPortfolio { Criteria = formula, MarginValue = marginValue, ParticipantCount = topCount }; return(SubscribeOnUserOrCustomPortfolio(hash, userLogin, localTime, portfolio, tradeAutoSettings)); }
public bool SubscribeOnService(ProtectedOperationContext secCtx, string login, int serviceId, bool renewAuto, bool unsubscribe, AutoTradeSettings tradeSets, out WalletError error) { try { return(Proxy.SubscribeOnService(secCtx, login, serviceId, renewAuto, unsubscribe, tradeSets, out error)); } catch (Exception) { RenewChannel(); return(Proxy.SubscribeOnService(secCtx, login, serviceId, renewAuto, unsubscribe, tradeSets, out error)); } }
public WalletError SubscribeOnTradeSignal( string hash, string userLogin, long localTime, int serviceId, bool tradeAuto, bool enableHedgingOrders, int percentLeverage, int maxVolume, int minVolume, int volumeStep, double maxLeverage) { var tradeSets = new AutoTradeSettings { TradeAuto = tradeAuto, HedgingOrdersEnabled = enableHedgingOrders, PercentLeverage = percentLeverage, MaxVolume = maxVolume, MinVolume = minVolume, StepVolume = volumeStep, MaxLeverage = maxLeverage }; try { using (var ctx = DatabaseContext.Instance.Make()) { var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == userLogin); if (user == null) { Logger.InfoFormat("PlatformManager.SubscribeOnTradeSignal(usr={0} not found)", userLogin); return(WalletError.InvalidData); } var userHash = CredentialsHash.MakeCredentialsHash(userLogin, user.Password, localTime); if (userHash != hash) { return(WalletError.AuthenticationError); } WalletError error; walletRepository.SubscribeOnService(ctx, user.ID, serviceId, true, false, tradeSets, out error); if (error != WalletError.OK) { Logger.InfoFormat("PlatformManager.SubscribeOnTradeSignal(usr={0}, login={1}, srv={2}): {3}", user.ID, userLogin, serviceId, error); } return(error); } } catch (Exception ex) { Logger.Error("Error in SubscribeOnTradeSignal()", ex); return(WalletError.ServerError); } }
public static SUBSCRIPTION_SIGNAL UndecorateAutoTradeSettings(AutoTradeSettings cat) { return(new SUBSCRIPTION_SIGNAL { FixedVolume = cat.FixedVolume, HedgingOrdersEnabled = cat.HedgingOrdersEnabled, MaxLeverage = cat.MaxLeverage, MaxVolume = cat.MaxVolume, MinVolume = cat.MinVolume, PercentLeverage = cat.PercentLeverage, StepVolume = cat.StepVolume, AutoTrade = cat.TradeAuto, VolumeRound = (int?)cat.VolumeRound }); }
public static string TradeSignalSetsAreCorrect(AutoTradeSettings sets, SUBSCRIPTION_SIGNAL setsStored) { var errors = new List <string>(); if ((int?)sets.VolumeRound != setsStored.VolumeRound) { errors.Add("VolumeRound"); } if (sets.HedgingOrdersEnabled != setsStored.HedgingOrdersEnabled) { errors.Add("HedgingOrdersEnabled"); } if (sets.PercentLeverage != setsStored.PercentLeverage) { errors.Add("PercentLeverage"); } if (sets.MinVolume != setsStored.MinVolume) { errors.Add("MinVolume"); } if (sets.StepVolume != setsStored.StepVolume) { errors.Add("StepVolume"); } if (sets.MaxLeverage != setsStored.MaxLeverage) { errors.Add("MaxLeverage"); } if (sets.MaxVolume != setsStored.MaxVolume) { errors.Add("MaxVolume"); } if (sets.TargetAccount != setsStored.TargetAccount) { errors.Add("TargetAccount"); } if (sets.TradeAuto != setsStored.AutoTrade) { errors.Add("TradeAuto"); } if (sets.FixedVolume != setsStored.FixedVolume) { errors.Add("FixedVolume"); } return(string.Join(", ", errors)); }
public static AutoTradeSettings MakeSampleTradeSettings() { var tradeSets = new AutoTradeSettings { VolumeRound = VolumeRoundType.Вверх, HedgingOrdersEnabled = true, PercentLeverage = 150, MinVolume = 50000, StepVolume = 20000, MaxLeverage = 11, MaxVolume = 500000, TradeAuto = true, FixedVolume = 10000 }; return(tradeSets); }
public RequestStatus ApplyPortfolioTradeSettings(ProtectedOperationContext secCtx, string login, AutoTradeSettings sets) { if (UserOperationRightsStorage.IsProtectedOperation(UserOperation.BindToSignal)) { if (!UserSessionStorage.Instance.PermitUserOperation(secCtx, UserOperationRightsStorage.IsTradeOperation(UserOperation.BindToSignal), false)) { return(RequestStatus.Unauthorized); } } try { using (var ctx = DatabaseContext.Instance.Make()) { var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == login); if (user == null) { return(RequestStatus.Unauthorized); } var subsription = ctx.USER_TOP_PORTFOLIO.FirstOrDefault(u => u.User == user.ID); if (subsription == null) { return(RequestStatus.CommonError); } subsription.AutoTrade = sets.TradeAuto; subsription.MaxLeverage = sets.MaxLeverage; subsription.PercentLeverage = sets.PercentLeverage; subsription.HedgingOrdersEnabled = sets.HedgingOrdersEnabled; subsription.FixedVolume = sets.FixedVolume; subsription.MinVolume = sets.MinVolume; subsription.MaxVolume = sets.MaxVolume; subsription.VolumeRound = (int?)sets.VolumeRound; subsription.StepVolume = sets.StepVolume; subsription.TargetAccount = sets.TargetAccount; ctx.SaveChanges(); return(RequestStatus.OK); } } catch (Exception ex) { Logger.Error("Ошибка в ApplyPortfolioTradeSettings()", ex); return(RequestStatus.ServerError); } }
public void TestPropertyDic() { var sets = new AutoTradeSettings { MaxLeverage = 6, TradeAuto = true }; var nameVal = UiFieldAttribute.GetAttributeNameValue(sets); Assert.Greater(nameVal.Count, 0); var cat = new AutoTradeSettings(); UiFieldAttribute.SetFieldsFromPropNameValue( nameVal.ToDictionary(p => p.PropName, p => Converter.GetStringFromObject(p.Value)), cat, false); Assert.AreEqual(sets.MaxLeverage, cat.MaxLeverage); Assert.AreEqual(sets.TradeAuto, cat.TradeAuto); }
private RequestStatus SubscribeOnUserOrCustomPortfolio(string hash, string userLogin, long localTime, TopPortfolio portfolio, AutoTradeSettings tradeAutoSettings) { if (portfolio == null) { Logger.Error("SubscribeOnUserOrCustomPortfolio(null)"); return(RequestStatus.BadRequest); } Logger.InfoFormat("SubscribeOnUserOrCustomPortfolio({0}, портфель {1})", userLogin, portfolio.Id > 0 ? "#" + portfolio.Id : portfolio.Criteria); try { using (var ctx = DatabaseContext.Instance.Make()) { var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == userLogin); if (user == null) { return(RequestStatus.Unauthorized); } var userHash = CredentialsHash.MakeCredentialsHash(userLogin, user.Password, localTime); if (userHash != hash) { return(RequestStatus.Unauthorized); } var status = walletRepository.SubscribeUserOnPortfolio(ctx, userLogin, portfolio, null, tradeAutoSettings); if (status != RequestStatus.OK) { Logger.Info("SubscribeOnUserOrCustomPortfolio: status: " + status); } return(status); } } catch (Exception ex) { Logger.Error("Ошибка в SubscribeOnUserOrCustomPortfolio()", ex); return(RequestStatus.ServerError); } }
public bool SubscribeOnService(ProtectedOperationContext secCtx, string login, int serviceId, bool renewAuto, bool unsubscribe, AutoTradeSettings tradeSets, out WalletError error) { if (!UserSessionStorage.Instance.PermitUserOperation(secCtx, false, false)) { error = WalletError.InsufficientRights; return(false); } // создать или удалить подписку try { using (var ctx = DatabaseContext.Instance.Make()) { // пользователь var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == login); if (user == null) { Logger.ErrorFormat("SubscribeOnService({0}, srv {1}) - пользователь не найден", login, serviceId); error = WalletError.InvalidData; return(false); } return(walletRepository.SubscribeOnService(ctx, user.ID, serviceId, renewAuto, unsubscribe, tradeSets, out error)); } } catch (Exception ex) { Logger.ErrorFormat("Ошибка в SubscribeOnService({0}): {1}", serviceId, ex); error = WalletError.ServerError; return(false); } }
public bool SubscribeOnService(TradeSharpConnection ctx, int userId, int serviceId, bool renewAuto, bool unsubscribe, AutoTradeSettings tradeSets, out WalletError error) { // имеющаяся подписка var subs = ctx.SUBSCRIPTION.FirstOrDefault(s => s.Service == serviceId && s.User == userId); // просто отписаться от сервиса if (unsubscribe) { error = WalletError.OK; if (subs == null) { return(true); } ctx.SUBSCRIPTION.Remove(subs); try { ctx.SaveChanges(); } catch (Exception ex) { Logger.Error("Ошибка удаления подписки (SubscribeOnService)", ex); error = WalletError.ServerError; return(false); } return(true); } var paidService = ctx.SERVICE.FirstOrDefault(s => s.ID == serviceId); if (paidService == null) { error = WalletError.InvalidData; return(false); } // проверить - не подписывается ли пользователь сам на себя? if (paidService.User == userId) { error = WalletError.InvalidData; return(false); } // провести списание денежных средств // содрать денежку var feeError = ChargeFeeOnSubscription(ctx, serviceId, userId, false); if (feeError != WalletError.OK) { error = feeError; return(false); } // продлить или обновить подписку var subExists = subs != null; if (subs == null) { subs = new SUBSCRIPTION(); } subs.RenewAuto = renewAuto; subs.TimeEnd = DateTime.Now.Date.AddDays(1); subs.TimeStarted = DateTime.Now.Date; subs.User = userId; subs.Service = serviceId; if (!subExists) { ctx.SUBSCRIPTION.Add(subs); } // обновить или создать настройки торговли var signalTradeSets = ctx.SUBSCRIPTION_SIGNAL.FirstOrDefault(s => s.Service == serviceId && s.User == userId); var setsExists = signalTradeSets != null; if (signalTradeSets == null) { signalTradeSets = new SUBSCRIPTION_SIGNAL(); } signalTradeSets.AutoTrade = tradeSets.TradeAuto; signalTradeSets.FixedVolume = tradeSets.FixedVolume; signalTradeSets.HedgingOrdersEnabled = tradeSets.HedgingOrdersEnabled; signalTradeSets.MaxLeverage = tradeSets.MaxLeverage; signalTradeSets.MaxVolume = tradeSets.MaxVolume; signalTradeSets.MinVolume = tradeSets.MinVolume; signalTradeSets.PercentLeverage = tradeSets.PercentLeverage; signalTradeSets.Service = serviceId; signalTradeSets.StepVolume = tradeSets.StepVolume; signalTradeSets.User = userId; signalTradeSets.TargetAccount = tradeSets.TargetAccount; signalTradeSets.VolumeRound = (int?)tradeSets.VolumeRound; if (!setsExists) { ctx.SUBSCRIPTION_SIGNAL.Add(signalTradeSets); } try { ctx.SaveChanges(); } catch (Exception ex) { Logger.Error("Ошибка сохранения подписки (SubscribeOnService)", ex); error = WalletError.ServerError; return(false); } error = WalletError.OK; return(true); }
public RequestStatus ApplyPortfolioTradeSettings(ProtectedOperationContext secCtx, string login, AutoTradeSettings sets) { throw new NotImplementedException(); }
public RequestStatus ApplyPortfolioTradeSettings(ProtectedOperationContext secCtx, string login, AutoTradeSettings sets) { try { return(Proxy.ApplyPortfolioTradeSettings(secCtx, login, sets)); } catch (Exception) { RenewChannel(); return(Proxy.ApplyPortfolioTradeSettings(secCtx, login, sets)); } }
public bool SubscribeOnService(ProtectedOperationContext secCtx, string login, int serviceId, bool renewAuto, bool unsubscribe, AutoTradeSettings tradeSets, out WalletError error) { error = WalletError.CommonError; return(false); }
public RequestStatus ApplyPortfolioTradeSettings(ProtectedOperationContext secCtx, string login, AutoTradeSettings sets) { return(Channel.ApplyPortfolioTradeSettings(secCtx, login, sets)); }
public RequestStatus SubscribeOnPortfolio(ProtectedOperationContext secCtx, string subscriberLogin, TopPortfolio portfolio, decimal?maxFee, AutoTradeSettings tradeAutoSettings) { return(Channel.SubscribeOnPortfolio(secCtx, subscriberLogin, portfolio, maxFee, tradeAutoSettings)); }
public RequestStatus SubscribeUserOnPortfolio( TradeSharpConnection ctx, string subscriberLogin, TopPortfolio portfolio, decimal?maxFee, AutoTradeSettings tradeAutoSettings) { var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == subscriberLogin); if (user == null) { return(RequestStatus.Unauthorized); } TOP_PORTFOLIO targetPortfolio = null; if (portfolio.Id > 0) { targetPortfolio = ctx.TOP_PORTFOLIO.FirstOrDefault(p => p.Id == portfolio.Id); } if (targetPortfolio != null) { portfolio.ManagedAccount = targetPortfolio.ManagedAccount; } // если портфель - пользовательский - сохранить его // для пользователя или обновить его имеющийся портфель if (!portfolio.IsCompanyPortfolio) { Logger.Info("SubscribeOnPortfolio() - user portfolio"); try { var existPortfolio = ctx.TOP_PORTFOLIO.FirstOrDefault(p => p.OwnerUser == user.ID); if (existPortfolio != null) { if (!LinqToEntity.DecoratePortfolio(existPortfolio).AreSame(portfolio)) { // удалить старый портфель пользователя ctx.TOP_PORTFOLIO.Remove(existPortfolio); existPortfolio = null; } else { targetPortfolio = existPortfolio; } } // создать портфель пользователя if (existPortfolio == null) { targetPortfolio = LinqToEntity.UndecoratePortfolio(portfolio); targetPortfolio.OwnerUser = user.ID; targetPortfolio.ManagedAccount = null; ctx.TOP_PORTFOLIO.Add(targetPortfolio); ctx.SaveChanges(); } } catch (DbEntityValidationException dbEx) { Logger.Error("SubscribeUserOnPortfolio - ошибка сохранения портфеля"); foreach (var validationErrors in dbEx.EntityValidationErrors) { foreach (var validationError in validationErrors.ValidationErrors) { Logger.ErrorFormat("Свойство: {0}, ошибка: {1}", validationError.PropertyName, validationError.ErrorMessage); } } } catch (Exception ex) { Logger.Error("Ошибка в SubscribeOnPortfolio() - обновление портфеля", ex); return(RequestStatus.ServerError); } } else {// портфель компании Logger.Info("SubscribeOnPortfolio() - company portfolio"); if (targetPortfolio == null) { Logger.Error("Пользователь запросил несуществующий портфель компании " + portfolio.Id); return(RequestStatus.ServerError); } } // очистить подписки пользователя на портфели // и привязать его к целевому портфелю //Logger.Info("SubscribeOnPortfolio() - removing bindings"); var oldBinding = ctx.USER_TOP_PORTFOLIO.FirstOrDefault(u => u.User == user.ID); // "посмотреть" настройки портфельной торговли в имеющейся подписке if (tradeAutoSettings == null) { if (oldBinding == null) { Logger.ErrorFormat("Подписка пользователя {0} на портфель {1} - нет данных по автоматической торговле", user.Login, portfolio.Id > 0 ? portfolio.Id.ToString() : portfolio.Name); return(RequestStatus.BadRequest); } tradeAutoSettings = new AutoTradeSettings { FixedVolume = oldBinding.FixedVolume, HedgingOrdersEnabled = oldBinding.HedgingOrdersEnabled, MaxLeverage = oldBinding.MaxLeverage, MaxVolume = oldBinding.MaxVolume, MinVolume = oldBinding.MinVolume, PercentLeverage = oldBinding.PercentLeverage ?? 100, StepVolume = oldBinding.StepVolume, TargetAccount = oldBinding.TargetAccount, TradeAuto = oldBinding.AutoTrade ?? false, VolumeRound = (VolumeRoundType?)oldBinding.VolumeRound }; } if (oldBinding != null) { ctx.USER_TOP_PORTFOLIO.Remove(oldBinding); } //Logger.Info("SubscribeOnPortfolio() - adding binding"); ctx.USER_TOP_PORTFOLIO.Add(new USER_TOP_PORTFOLIO { User = user.ID, Portfolio = targetPortfolio.Id, MaxFee = maxFee, AutoTrade = tradeAutoSettings.TradeAuto, MaxLeverage = tradeAutoSettings.MaxLeverage, PercentLeverage = tradeAutoSettings.PercentLeverage, HedgingOrdersEnabled = tradeAutoSettings.HedgingOrdersEnabled, FixedVolume = tradeAutoSettings.FixedVolume, MinVolume = tradeAutoSettings.MinVolume, MaxVolume = tradeAutoSettings.MaxVolume, VolumeRound = (int?)tradeAutoSettings.VolumeRound, StepVolume = tradeAutoSettings.StepVolume, TargetAccount = tradeAutoSettings.TargetAccount }); ctx.SaveChanges(); //Logger.Info("SubscribeOnPortfolio() - changes are saved"); // найти трейдеров, удовлетворяющих критерию List <PerformerStat> performers; try { try { performers = TradeSharpAccountStatistics.Instance.proxy.GetAllPerformersWithCriteria(true, targetPortfolio.Criteria, targetPortfolio.ParticipantCount, !targetPortfolio.DescendingOrder, (float?)targetPortfolio.MarginValue, 0); } catch (Exception ex) { Logger.Error( "Ошибка в SubscribeOnPortfolio() - получение перформеров (" + targetPortfolio.Criteria + ")", ex); return(RequestStatus.ServerError); } if (performers == null) { Logger.Error("Ошибка в SubscribeOnPortfolio() - список перформеров не получен (" + targetPortfolio.Criteria + ")"); return(RequestStatus.ServerError); } } catch (Exception ex) { Logger.Error("Ошибка в SubscribeOnPortfolio() - подписка", ex); return(RequestStatus.ServerError); } // сравнить полученный список с текущими подписками заказчика ("инвестора") // сформировать список для "отписки" и список для подписки var performerAcs = performers.Select(p => p.Account).ToList(); var subsToRemove = ctx.SUBSCRIPTION.Where(s => s.User == user.ID && s.SERVICE1.ServiceType == (int)PaidServiceType.Signals && !performerAcs.Contains(s.SERVICE1.AccountId ?? 0)).ToList(); foreach (var sub in subsToRemove) { WalletError error; SubscribeOnService(ctx, user.ID, sub.Service, false, true, tradeAutoSettings, out error); if (error != WalletError.OK) { Logger.ErrorFormat("Portfolio - unsubscribe user {0} from srv {1}: error {2}", user.ID, sub.Service, error); } } // новоподписавшиеся foreach (var pf in performers) { WalletError error; SubscribeOnService(ctx, user.ID, pf.Service, true, false, tradeAutoSettings, out error); if (error != WalletError.OK) { Logger.DebugFormat("Подписка SubscribeOnPortfolio({0}), сигн. {1}: {2}", subscriberLogin, pf.Service, error); } } return(RequestStatus.OK); }
public bool SubscribeOnService(ProtectedOperationContext secCtx, string login, int serviceId, bool renewAuto, bool unsubscribe, AutoTradeSettings tradeSets, out WalletError error) { throw new NotImplementedException(); }
public RequestStatus SubscribeOnPortfolio(ProtectedOperationContext secCtx, string subscriberLogin, TopPortfolio portfolio, decimal?maxFee, AutoTradeSettings tradeSets) { throw new NotImplementedException(); }
public AutoTradeSettingsForm(AutoTradeSettings sets) : this() { this.sets = sets; tradeSettings.DataContext = sets.MakeCopy(); }
public RequestStatus SubscribeOnPortfolio(ProtectedOperationContext secCtx, string subscriberLogin, TopPortfolio portfolio, decimal?maxFee, AutoTradeSettings tradeAutoSettings) { try { return(Proxy.SubscribeOnPortfolio(secCtx, subscriberLogin, portfolio, maxFee, tradeAutoSettings)); } catch (Exception) { RenewChannel(); return(Proxy.SubscribeOnPortfolio(secCtx, subscriberLogin, portfolio, maxFee, tradeAutoSettings)); } }
public RequestStatus SubscribeOnPortfolio(ProtectedOperationContext secCtx, string subscriberLogin, TopPortfolio portfolio, decimal?maxFee, AutoTradeSettings tradeAutoSettings) { return(RequestStatus.CommonError); }