async Task FillTestParams(TradingMacro tmOriginal, Action <IList <KeyValuePair <string, object>[]> > paramsTransformation) { var c = _testParamValuesSeparators; if (!_testParamsRaw.Any()) { if (!ReplayArguments.IsWww && tmOriginal.UseTestFile) { var od = new Microsoft.Win32.OpenFileDialog() { FileName = "TestParams", DefaultExt = ".txt", Filter = "Text documents(.txt)|*.txt" }; var odRes = od.ShowDialog(); if (!odRes.GetValueOrDefault()) { throw new ArgumentException("Must provide test params file name."); } tmOriginal.TestFileName = System.IO.Path.GetFileName(od.FileName); if (tmOriginal.TestFileName.Contains("skipme")) { tmOriginal.TestFileName = ""; } else { var paramsDict = Lib.ReadTestParameters(od.FileName); _testParamsRaw.AddRange(paramsDict.Select(kv => kv.Value.Split(c).Select(v => new KeyValuePair <string, object>(kv.Key, v)).ToArray())); } } else if (ReplayArguments.IsWww) { ReplayArguments.LastWwwError = ""; var strats = TaskMonad.RunSync(() => ReadStrategies(tmOriginal, (name, desc, content, uri, diff) => new { name, content, diff })); Func <string, bool> isTest = s => s.ToLower().Trim().EndsWith("{t}"); await strats.Select(s => s.First()) .Take(2) .OrderByDescending(s => isTest(s.name)) .Where(s => isTest(s.name) || s.diff.IsEmpty()) .OnEmpty(() => { LogWww(new Exception(ReplayArguments.LastWwwError = "Current settings don't match any strategy")); }) .Select(strategy => { tmOriginal.TestFileName = strategy.name; var paramsDict = Lib.ReadParametersFromString(strategy.content); _testParamsRaw.AddRange( paramsDict .Select(kv => kv.Value.Split(c).Select(v => new KeyValuePair <string, object>(kv.Key, v)) .ToArray())); return(tmOriginal.LoadActiveSettings(strategy.name, TradingMacro.ActiveSettingsStore.Gist)); }).WhenAll(); } else { var testParams = tmOriginal.GetPropertiesByAttibute <CategoryAttribute>(a => a.Category == TradingMacro.categoryTest); var paramsDict = testParams.ToDictionary(p => p.Item2.Name.Substring(4), p => p.Item2.GetValue(tmOriginal, null).ToString().ParseParamRange()); _testParamsRaw.AddRange(paramsDict.Where(kv => !string.IsNullOrWhiteSpace(kv.Value)) .Select(kv => kv.Value.Split(c).Select(v => new KeyValuePair <string, object>(kv.Key, v)).ToArray())); } } TestParams.Clear(); paramsTransformation(_testParamsRaw); _testParamsRaw.CartesianProduct().ForEach(tp => TestParams.Enqueue(tp.ToArray())); }
async Task StartReplay(TradingMacro tm) { TradingMacro tmOriginal = (TradingMacro)tm; if (!IsLoggedIn) { LogWww(new Exception("Must login first.")); return; } try { while (_replayTasks.ToArray().Any(t => t.Status == TaskStatus.Running)) { if (ReplayArguments.IsWww) { ReplayArguments.LastWwwError = "Replay is running"; return; } Log = new Exception("Replay is running."); Thread.Sleep(1000); continue; } ReplayArguments.Initiator = tmOriginal; ReplayArguments.StartingBalance = tmOriginal.TestBalance; ReplayArguments.PrevSessionUid = tmOriginal.TestPrevSession; ReplayArguments.SuperSessionId = tmOriginal.TestSuperSessionUid.ValueOrDefault(Guid.NewGuid()); _testParamsRaw.Clear(); tmOriginal.TestFileName = ""; if (ReplayArguments.UseSuperSession) { #region getDateFromSuperSession Func <Task <DateTime> > getDateFromSuperSession = async() => { try { var sessions = GetBestSessions(ReplayArguments.SuperSessionId).ToArray(); if (sessions.Any()) { await FillTestParams(tmOriginal, tpr => { }); } else { throw new Exception("Either ReplayArguments.DateStart or valid Supersession Uid must be provided."); } return(sessions.Min(s => s.DateStart.Value).AddDays(5)); } catch (Exception exc) { Log = exc; throw; } }; #endregion ReplayArguments.DateStart = ReplayArguments.DateStart ?? await getDateFromSuperSession(); } await FillTestParams(tmOriginal, pt => { }); Log = new Exception("Starting testing with {0} sets.".Formater(TestParams.Count)); StartReplayInternal(tmOriginal, TestParams.Any() ? TestParams.Dequeue() : null, task => { ContinueReplayWith(tmOriginal, TestParams); }); } catch (Exception exc) { Log = exc; } }
void SaveTradingSettings(TradingMacro tmOriginal) { try { var attrs = new[] { TradingMacro.categoryActive, TradingMacro.categoryActiveFuncs }; tmOriginal.GetPropertiesByAttibute <CategoryAttribute>(a => attrs.Contains(a.Category)) .GroupBy(a => a.Item2.Name).ToList().ForEach(g => { }); //.ForEach(p => Debug.WriteLine("{0}={1}", p.Name, p.GetValue(tmOriginal, null))); } catch { } }
public void IsTradingHour() { var d = DateTime.Parse("1:00"); var d2 = DateTime.Parse("17:00"); var d3 = DateTime.Parse("00:00"); Assert.IsTrue(TradingMacro.IsTradingHour("", d)); Assert.IsTrue(TradingMacro.IsTradingHour("", d3)); Assert.IsTrue(TradingMacro.IsTradingHour("0:29-1:01", d)); Assert.IsFalse(TradingMacro.IsTradingHour("0:29-1:01", d2)); Assert.IsTrue(TradingMacro.IsTradingHour("21:00-1:00", d)); Assert.IsFalse(TradingMacro.IsTradingHour("21:00-1:00", d2)); }
public void IsTradingHour2() { var range = TradingMacro.ParseTimeRangeTimeSpans("[['9:00','17:00']]"); Assert.IsTrue(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("10:00")))); Assert.IsFalse(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("17:30")))); range = TradingMacro.ParseTimeRangeTimeSpans("[['9:00','17:00'],['17:30','17:40']]"); Assert.IsTrue(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("17:30")))); Assert.IsTrue(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("9:30")))); Assert.IsFalse(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("17:20")))); Assert.IsTrue(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("17:20")))); Assert.IsTrue(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("9:00")))); Assert.IsFalse(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("16:20")))); Assert.IsFalse(TradingMacro.IsTradingHour2Impl((range, DateTime.Parse("9:20")))); }
void ContinueReplayWith(TradingMacro tm, Queue <TestParam> testParams) { try { if (tm.Strategy == Strategies.None) { return; } if (testParams.Any()) { StartReplayInternal(tm, testParams.Dequeue(), t => { ContinueReplayWith(tm, testParams); }); } else { ReplayArguments.LastWwwErrorObservable.OnNext("Replay done"); } } catch (Exception exc) { Log = exc; } }
public void GetTradeConditions() { var tcs = new TradingMacro().GetTradeConditions(); Assert.IsTrue(tcs != null); }
void StartReplayInternal(TradingMacro tmOriginal, TestParam testParameter, Action <Task> continueWith) { if (IsInVirtualTrading) { while (_replayTasks.ToArray().Any(t => t.Status == TaskStatus.Running)) { Log = new Exception("Replay is running."); Thread.Sleep(1000); continue; } _replayTasks.Clear(); MasterModel.AccountModel.Balance = MasterModel.AccountModel.Equity = 50000; MasterModel.AccountModel.CurrentGrossInPips = 0; MasterModel.AccountModel.CurrentLoss = 0; TradesManager.GetAccount().Balance = TradesManager.GetAccount().Equity = 50000; } SaveTradingSettings(tmOriginal); var tms = GetTradingMacros().Where(t => t.IsActive).ToList(); ReplayArguments.SetTradingMacros(tms); ReplayArguments.GetOriginalBalance = new Func <double>(() => MasterModel.AccountModel.OriginalBalance); foreach (var tm in tms) { if (IsInVirtualTrading) { if (tm.Strategy == Strategies.None) { tm.Strategy = Strategies.UniversalA; } TradesManager.ClosePair(tm.Pair); tm.ResetSessionId(ReplayArguments.SuperSessionId); if (testParameter != null && tm == tmOriginal) { testParameter.ForEach(tp => { try { tm.LoadSetting(tp); } catch (SetLotSizeException) { } catch (Exception exc) { if (!(exc.InnerException is SetLotSizeException)) { var e2 = new Exception("Property:" + new { tp.Key, tp.Value }, exc); LogWww(e2); throw e2; } } }); } } if (!string.IsNullOrWhiteSpace(ReplayArguments.PrevSessionUid)) { TradingMacro.SessionId = Guid.Parse(ReplayArguments.PrevSessionUid); } var tmToRun = tm; tmToRun.ReplayCancelationToken = (_replayTaskCancellationToken = new CancellationTokenSource()).Token; var task = Task.Factory.StartNew(() => tmToRun.Replay(ReplayArguments), tmToRun.ReplayCancelationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default); task.ContinueWith(t => { RxApp.MainThreadScheduler.Schedule(() => _replayTasks.Remove(t)); if (tm == tmOriginal) { continueWith(t); } }); _replayTasks.Add(task); ReplayArguments.IsWww = false; } }
public object[] ServeChart(int chartWidth, DateTimeOffset dateStart, DateTimeOffset dateEnd, TradingMacro tm) { var digits = tm.Digits(); if (dateEnd > tm.LoadRatesStartDate2) { dateEnd = tm.LoadRatesStartDate2; } else { dateEnd = dateEnd.AddMinutes(-tm.BarPeriodInt.Min(2)); } string pair = tm.Pair; Func <Rate, double> rateHL = rate => (rate.PriceAvg >= rate.PriceCMALast ? rate.PriceHigh : rate.PriceLow).Round(digits); #region map var rth = new[] { new TimeSpan(9, 30, 0), new TimeSpan(16, 0, 0) }; var rthDates = MonoidsCore.ToFunc((DateTime dt) => dt.Date.With(d => rth.Select(h => d + h)).ToArray()).MemoizeLast(dt => dt.Date); bool isRth(DateTime dt) { return(dt.Between(rthDates(dt))); } var doShowVolt = tm.VoltageFunction != VoltageFunction.None; var doShowVolt2 = tm.VoltageFunction2 != VoltageFunction.None || tm.VoltageFunction == VoltageFunction.PPMH; var lastVolt = tm.GetLastVolt().DefaultIfEmpty().Memoize(); var lastVolt2 = tm.GetLastVolt(tm.GetVoltage2).DefaultIfEmpty().Memoize(); var lastCma = tm.UseRates(TradingMacro.GetLastRateCma).SelectMany(cma => cma).FirstOrDefault(); var tsMin = TimeSpan.FromMinutes(tm.BarPeriodInt); var priceHedge = MonoidsCore.ToFunc((Rate r) => r.PriceHedge).MemoizePrev(d => d.IsZeroOrNaN()); var map = MonoidsCore.ToFunc((Rate)null, rate => new { //d = rate.StartDate2, d = tm.BarPeriod == BarsPeriodType.t1 ? rate.StartDate2 : rate.StartDate2.Round().With(d => d == rate.StartDate2 ? d : d + tsMin), c = rateHL(rate), v = doShowVolt ? tm.GetVoltage(rate).IfNaNOrZero(lastVolt) : 0, v2 = doShowVolt2 ? tm.GetVoltage2(rate).IfNaNOrZero(lastVolt2) : 0, m = rate.PriceCMALast.IfNaNOrZero(lastCma).Round(digits), a = rate.AskHigh.Round(digits), b = rate.BidLow.Round(digits), h = isRth(rate.StartDate.InNewYork()), p = priceHedge(rate) }); #endregion var exit = false;// doShowVolt && lastVolt.IsEmpty() || doShowVolt2 && lastVolt2.IsEmpty(); if (exit || tm.RatesArray.Count == 0 || tm.IsTrader && tm.BuyLevel == null) { return new[] { new { rates = new int[0] } } } ; var tmTrader = GetTradingMacros(tm.Pair).Where(t => t.IsTrader).DefaultIfEmpty(tm).Single(); var tpsHigh = tm.GetVoltageHigh().SingleOrDefault(); var tpsLow = tm.GetVoltageAverage().SingleOrDefault(); var tps2High = tm.GetVoltage2High().Where(v => !v.IsNaN()).ToArray(); var tps2Low = tm.GetVoltage2Low().Where(v => !v.IsNaN()).ToArray(); var tpsCurr2 = tm.UseRates(ra => ra.BackwardsIterator().Select(tm.GetVoltage2).SkipWhile(double.IsNaN).FirstOrDefault()).DefaultIfEmpty(0).Single(); var ratesForChart = tm.UseRates(rates => rates.Where(r => r.StartDate2 >= dateEnd /* && !tm.GetVoltage(r).IsNaNOrZero()*/).ToList()).FirstOrDefault(); if (ratesForChart == null) { return(new object[0]); } var ratesForChart2 = tm.UseRates(rates => rates.Where(r => r.StartDate2 < dateStart /* && !tm.GetVoltage(r).IsNaNOrZero()*/).ToList()).FirstOrDefault(); if (ratesForChart2 == null) { return(new object[0]); } double cmaPeriod = tm.CmaPeriodByRatesCount(); if (tm.IsTicks) { Action <IList <Rate>, Rate> volts = (gr, r) => { if (doShowVolt) { tm.SetVoltage(r, gr.Select(tm.GetVoltage).Where(v => v.IsNotNaN()).DefaultIfEmpty(lastVolt.First()).Average()); } if (doShowVolt2) { tm.SetVoltage2(r, gr.Select(tm.GetVoltage2).Where(v => v.IsNotNaN()).DefaultIfEmpty(lastVolt2.First()).Average()); } }; cmaPeriod /= tm.TicksPerSecondAverage; if (ratesForChart.Count > 1) { ratesForChart = TradingMacro.GroupTicksToSeconds(ratesForChart, volts).ToList(); } if (ratesForChart2.Count > 1) { ratesForChart2 = TradingMacro.GroupTicksToSeconds(ratesForChart2, volts).ToList(); } } var getRates = MonoidsCore.ToFunc((IList <Rate>)null, rates3 => rates3.Select(map).ToList()); var tradeLevels = tmTrader.Strategy != Strategies.Universal || !tmTrader.HasBuyLevel ? new object { } : new { buy = tmTrader.BuyLevel.Rate.Round(digits), buyClose = tmTrader.BuyCloseLevel.Rate.Round(digits), canBuy = tmTrader.BuyLevel.CanTrade, manualBuy = tmTrader.BuyLevel.InManual, buyCount = tmTrader.BuyLevel.TradesCount, sell = tmTrader.SellLevel.Rate.Round(digits), sellClose = tmTrader.SellCloseLevel.Rate.Round(digits).With(d => d == 0 ? tmTrader.RatesArray[0].PriceAvg : d), canSell = tmTrader.SellLevel.CanTrade, manualSell = tmTrader.SellLevel.InManual, sellCount = tmTrader.SellLevel.TradesCount, }; /* * if (tm.IsAsleep) { * var o = new object(); * var a = new object[0]; * return new { * rates = getRates(ratesForChart), * rates2 = getRates(ratesForChart2), * ratesCount = tm.RatesArray.Count, * dateStart = tm.RatesArray[0].StartDate2, * trendLines = o, * trendLines2 = o, * trendLines1 = o, * isTradingActive = tm.IsTradingActive, * tradeLevels = o, * trades = a, * askBid = o, * hasStartDate = tm.CorridorStartDate.HasValue, * cmp = cmaPeriod, * tpsAvg = 0, * isTrader = tm.IsTrader, * canBuy = false, * canSell = false, * waveLines = a * }; * } */ Func <Lazy <IList <Rate> >, IList <Rate> > safeTLs = tls => tls.Value ?? new List <Rate>(); var trends = safeTLs(tm.TrendLines); var trendLines = new { dates = trends.Count > 1 ? new DateTimeOffset[] { trends[0].StartDate2, trends[1].StartDate2 } : new DateTimeOffset[0], close1 = trends.ToArray(t => t.Trends.PriceAvg1.Round(digits)), close2 = trends.ToArray(t => t.Trends.PriceAvg2.Round(digits)), close3 = trends.ToArray(t => t.Trends.PriceAvg3.Round(digits)), sel = TradingMacro.IsTrendsEmpty(trends).IsSelected //close21 = trends.ToArray(t => t.Trends.PriceAvg21.Round(digits)), //close31 = trends.ToArray(t => t.Trends.PriceAvg31.Round(digits)) }; var ratesLastStartDate2 = tm.RatesArray.Last().StartDate2; var trends2 = safeTLs(tm.TrendLines2); var trendLines2 = new { dates = trends2.Count == 0 ? new DateTimeOffset[0] : new DateTimeOffset[] { trends2[0].StartDate2, trends2[1].StartDate2 }, close1 = trends2.ToArray(t => t.Trends.PriceAvg1.Round(digits)), close2 = trends2.ToArray(t => t.Trends.PriceAvg2.Round(digits)), close3 = trends2.ToArray(t => t.Trends.PriceAvg3.Round(digits)), sel = TradingMacro.IsTrendsEmpty(trends2).IsSelected }; var trends0 = safeTLs(tm.TrendLines0); var trendLines0 = new { dates = trends0.Count == 0 ? new DateTimeOffset[0] : new DateTimeOffset[] { trends0[0].StartDate2, trends0[1].StartDate2 }, close2 = trends0.ToArray(t => t.Trends.PriceAvg2.Round(digits)), close3 = trends0.ToArray(t => t.Trends.PriceAvg3.Round(digits)), sel = TradingMacro.IsTrendsEmpty(trends0).IsSelected }; var trends1 = safeTLs(tm.TrendLines1); var trendLines1 = new { dates = trends1.Count == 0 ? new DateTimeOffset[0] : new DateTimeOffset[] { trends1[0].StartDate2, trends1[1].StartDate2 }, close2 = trends1.ToArray(t => t.Trends.PriceAvg2.Round(digits)), close3 = trends1.ToArray(t => t.Trends.PriceAvg3.Round(digits)), sel = TradingMacro.IsTrendsEmpty(trends1).IsSelected }; var trends3 = safeTLs(tm.TrendLines3); var trendLines3 = new { dates = trends3.Count == 0 ? new DateTimeOffset[0] : new DateTimeOffset[] { trends3[0].StartDate2, trends3[1].StartDate2 }, close2 = trends3.ToArray(t => t.Trends.PriceAvg2.Round(digits)), close3 = trends3.ToArray(t => t.Trends.PriceAvg3.Round(digits)), sel = TradingMacro.IsTrendsEmpty(trends3).IsSelected }; var waveLines = tm.WaveRangesWithTail .ToArray(wr => new { dates = new[] { wr.StartDate, wr.EndDate }, isept = new[] { wr.InterseptStart, wr.InterseptEnd }, isOk = wr.IsFatnessOk }); var tmg = TradesManager; var trades0 = tmg.GetTrades(); Func <bool, Trade[]> getTrades = isBuy => trades0.Where(t => t.IsBuy == isBuy).ToArray(); var trades = new ExpandoObject(); var tradeFoo = MonoidsCore.ToFunc(false, isBuy => new { o = getTrades(isBuy).NetOpen(), t = getTrades(isBuy).Max(t => t.Time) }); getTrades(true).Take(1).ForEach(_ => trades.Add(new { buy = tradeFoo(true) })); getTrades(false).Take(1).ForEach(_ => trades.Add(new { sell = tradeFoo(false) })); if (!tmg.TryGetPrice(pair, out var price)) { return(new object[0]); } var askBid = new { ask = price.Ask.Round(digits), bid = price.Bid.Round(digits) }; var ish = tm.IsPairHedged; var hph = !tm.PairHedge.IsNullOrWhiteSpace(); var ret = tm.UseRates(ratesArray => ratesArray.Take(1).ToArray(), x => x).ToArray(_ => new { rates = getRates(ratesForChart), rates2 = getRates(ratesForChart2), ratesCount = tm.RatesArray.Count, dateStart = tm.RatesArray[0].StartDate2, trendLines0, trendLines, trendLines2, trendLines1, trendLines3, isTradingActive = tm.IsTradingActive, tradeLevels = tradeLevels, trades, askBid, hasStartDate = tm.CorridorStartDate.HasValue, cmp = cmaPeriod, tpsHigh, tps2Low, tps2High, tpsLow, tpsCurr2, isTrader = tm.IsTrader, canBuy = tmTrader.CanOpenTradeByDirection(true), canSell = tmTrader.CanOpenTradeByDirection(false), waveLines, barPeriod = tm.BarPeriodInt, ish, hph, vfs = tm.IsVoltFullScale ? 1 : 0, vfss = ish || tm.IsVoltFullScale ? tm.VoltsFullScaleMinMax : new[] { 0.0, 0.0 } }); return(ret); } }
public static async Task LoadStrategy(TradingMacro tm, string strategy) { await tm.LoadActiveSettings(strategy, TradingMacro.ActiveSettingsStore.Gist); }
public static async Task UpdateStrategy(TradingMacro tm, string nick) { await tm.SaveActiveSettings(nick, TradingMacro.ActiveSettingsStore.Gist); //File.Delete(path); }
//private static string StrategiesPath(string pathEnd = "") { // return Path.Combine(Directory.GetCurrentDirectory(), "..", "Strategies", pathEnd); //} public static async Task SaveStrategy(TradingMacro tm, string nick) { await tm.SaveActiveSettings(nick, TradingMacro.ActiveSettingsStore.Gist); }
public static async Task <IEnumerable <IEnumerable <T> > > ReadStrategies <T>(TradingMacro tmTrader, Func <string, string, string, Uri, string[], T> map) { var localMap = MonoidsCore.ToFunc("", "", "", (Uri)null, (name, description, content, uri) => new { name, description, content, uri }); var strategiesAll = (await Cloud.GitHub.GistStrategies(localMap)).ToArray(); var activeSettings = tmTrader.TradingMacrosByPair().ToArray(tm => tm.Serialize(true)); return(from strategies in strategiesAll let diffs = strategies.Zip(activeSettings, (strategy, activeSetting) => TradingMacro.ActiveSettingsDiff(strategy.content, activeSetting).ToDictionary()) .Select((diff, i) => diff.Select(kv => new { diff = i + ":" + kv.Key + "= " + kv.Value[0] + " {" + kv.Value[1] + "}", lev = Lib.LevenshteinDistance(kv.Value[0], kv.Value[1]) }).ToArray()) //.OrderBy(x=> x.Sum(d=>d.diff.Length))//.ThenBy(x=>x[0], diff.Sum(x => x.lev), strategy.name orderby diffs.Sum(d => d.Length) select strategies.Select(strategy => map(strategy.name, strategy.description, strategy.content, strategy.uri, diffs.SelectMany(a => a.Select(x => x.diff)).ToArray())) ); }