private decimal _lastCoin = -1; // non si puo' usare decimal.MinValue public override bool OnHeartBeat() { const decimal gain = 0M; // sellat, buyat // devo vendere o devo comprare? var action = this.SuggestedAction; /* * // mi salvo il massimo value * if (Market.TotValue > this.MaxValue) * { * this.MaxValue = Market.TotValue; * } * * if (Market.TotCoins > this.MaxCoins) * { * this.MaxCoins = Market.TotCoins; * } */ /************************************************************** * CHECK CONFERMA (DOPPIO COMANDO) **************************************************************/ // questa parte di codice esegue l'operazione se c'è una conferma if (action != TradeAction.StrongBuy && action != TradeAction.StrongSell) { if (action != _lastTradeActionSuggested) { //CUtility.Log("refused: wait confirm with 2nd command"); LogTrade.Motivation = "refused: wait confirm with 2nd command"; _lastTradeActionSuggested = action; action = TradeAction.Unknown; } } else { LogTrade.Motivation = ("refused: single command"); _lastTradeActionSuggested = TradeAction.Unknown; } LogTrade.Action = action; /************************************************************** * BUY **************************************************************/ // compro o vendo? string orderId = ""; if (action == TechnicalAnalysis.TradeAction.Buy || action == TechnicalAnalysis.TradeAction.StrongBuy) { /* * per comprare devo usare il valore ask */ var buyvalue = Market.Buy; var money = (Market.TotMoney - SavedMoney) * PercCapital; // impegno solo una percentuale del capitale SavedMoney += (Market.TotMoney - SavedMoney) * (1 - PercCapital); if (money == 0) { LogTrade.Motivation = ("refused: no money"); goto exitif; } if (PercCapital < 1.0M) { // se uso una percentuale, allora devo evitare che ripetuti comandi // uguali, mi facciamo dissipare il risparmio accantonato if (_lastTradeActionExecuted == CUtility.OrderType.Buy) { goto exitif; } } if (Conservative) { // impegno sempre non più di una certa cifra // sia per vendere che per comprare if (money > MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest) { SavedMoney += (money - MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest); money = MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest; } } var amount = money / buyvalue; // coins if (amount > MinBitCoin) { // compro solo se i coin risultanti sono più dei precedenti var coins = (amount) * (1 - Market.Fee); /* onlyIfGain attiva o disattiva il blocco delle vendite se i soldi ricavati sono inferiori rispetto alla vendita precedente */ var onlyIfGain = MainConfiguration.Configuration.GreedyWithCoins; // --> disabilità il blocco var greedyPerc = MainConfiguration.Configuration.GreedyWithCoinsGain; if (MainConfiguration.Configuration.GreedyWithLongTermTrend) { // diventa avido se il trend a lungo termine è in discesa onlyIfGain = this.CurrentLongTermTrend == Trend.Fall; var longTermCoefficienteAngolare = this.Market.CandleMaker.LongTermTrendSpeed(); greedyPerc = GreedyNess(longTermCoefficienteAngolare); } if (!onlyIfGain || action == TechnicalAnalysis.TradeAction.StrongBuy || coins > _lastCoin * greedyPerc) { // evito che il trading mi mandi sotto del numero iniziale di coins if (MainConfiguration.Configuration.UndervalueAllowed || (coins + SavedCoins) > MainConfiguration.Configuration.StartWalletCoins * (1 - MainConfiguration.Configuration.UndervalueTolerance)) { _lastCoin = coins; var result = Market.DoOrder(CUtility.OrderType.Buy, buyvalue, amount, ref orderId, true); if (result.Length > 0) { LogTrade.Motivation = "BUY"; _lastTradeActionExecuted = CUtility.OrderType.Buy; TotBid++; // avvisa l'analitic che l'ultima label inserita con AnalyticsTools.Call(xxxx) è completata AnalyticsTools.Confirm(); SellAt = (1 + gain) * (buyvalue * (1 + (2 * Market.Fee))); BuyAt = 0; } else { // c'è stato un fallimento LogTrade.Motivation = "BUY FAILED"; } } else { LogTrade.Motivation = ("under my initial value"); } } else { LogTrade.Motivation = ("greedy of coins: waiting for better performance " + Math.Round(_lastCoin * greedyPerc, 4).ToString(CultureInfo.InvariantCulture)); } } // _stoploss.Reset(); } /************************************************************** * SELL **************************************************************/ if (action == TechnicalAnalysis.TradeAction.Sell || action == TechnicalAnalysis.TradeAction.StrongSell) { var sellvalue = Market.Sell; var amount = (Market.TotCoins - SavedCoins) * PercCapital;// - SavedCoins; SavedCoins += (Market.TotCoins - SavedCoins) * (1 - PercCapital); if (amount == 0) { LogTrade.Motivation = ("refused: no coins"); goto exitif; } if (PercCapital < 1.0M) { // se uso una percentuale, allora devo evitare che ripetuti comandi // uguali, mi facciamo dissipare il risparmio accantonato if (_lastTradeActionExecuted == CUtility.OrderType.Sell) { goto exitif; } } if (Conservative) { // impegno sempre non più di una certa cifra // sia per vendere che per comprare var maxmoney = MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest; if (amount > maxmoney / sellvalue) { SavedCoins += (amount - maxmoney / sellvalue); if (SavedCoins > 100) { CUtility.Log("error"); } amount = maxmoney / sellvalue; } } if (amount > MinBitCoin) { var money = (amount * sellvalue) * (1 - Market.Fee); /* onlyIfGain attiva o disattiva il blocco delle vendite se i soldi ricavati sono inferiori rispetto alla vendita precedente */ var onlyIfGain = MainConfiguration.Configuration.GreedyWithMoney; // --> disabilita il blocco var greedyPerc = MainConfiguration.Configuration.GreedyWithMoneyGain; if (MainConfiguration.Configuration.GreedyWithLongTermTrend) { // diventa avido se il trend a lungo termine è in salita onlyIfGain = this.CurrentLongTermTrend == Trend.Raise; var longTermCoefficienteAngolare = this.Market.CandleMaker.LongTermTrendSpeed(); greedyPerc = GreedyNess(longTermCoefficienteAngolare); } if (!onlyIfGain || action == TechnicalAnalysis.TradeAction.StrongSell || money > _lastMoney * greedyPerc) { // evito che il trading mi butti sotto del numero iniziale di soldi if (MainConfiguration.Configuration.UndervalueAllowed || (money + SavedMoney) > MainConfiguration.Configuration.StartWalletMoney * (1 - MainConfiguration.Configuration.UndervalueTolerance)) { // vendo solo se la vendita produce piu' soldi di prima _lastMoney = money; var result = Market.DoOrder(CUtility.OrderType.Sell, sellvalue, amount, ref orderId, true); if (result.Length > 0) { TotAsk++; BuyAt = (1 - gain) * (sellvalue * (1 - (2 * Market.Fee))); SellAt = 0; // avvisa l'analitic che l'ultima label inserita con AnalyticsTools.Call(xxxx) è completata AnalyticsTools.Confirm(); _lastTradeActionExecuted = CUtility.OrderType.Sell; LogTrade.Motivation = "SELL"; } else { LogTrade.Motivation = "SELL FAILED"; } /* * if (action == TechnicalAnalysis.TradeAction.SellStopLoss) * { * TotStopLoss++; * } */ } else { LogTrade.Motivation = ("under my initial value"); } } else { LogTrade.Motivation = ("greedy of money: waiting for better performance " + Math.Round(_lastMoney * greedyPerc, 4).ToString(CultureInfo.InvariantCulture)); } } } exitif: /************************************************************** * LOG **************************************************************/ Log(string.Format("B:{0} A:{1} SL:{2} Max$:{3} MaxC:{4} MaxV:{5}", TotBid, TotAsk, 0, Math.Round(Market.MaxMoney, 4).ToString(CultureInfo.InvariantCulture), Math.Round(Market.MaxCoins, 4).ToString(CultureInfo.InvariantCulture), Math.Round(Market.MaxValue, 4).ToString(CultureInfo.InvariantCulture))); LogTrade.BuyAt = BuyAt; LogTrade.SellAt = SellAt; return(true); }
public override TradeAction SuggestedAction(CMarket market) { /******************************************************************************** * CONSERVATIVE DYNAMIC * ********************************************************************************/ if (MainConfiguration.Configuration.ManagerIsConservative && MainConfiguration.Configuration.ManagerConservativeTimesPerValue > 0) { MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest = ((market.Buy + market.Sell) / 2) * MainConfiguration.Configuration.ManagerConservativeTimesPerValue; } /******************************************************************************** * EVALUATION * vengono esaminati i comandi ed eseguiti uno ad uno ********************************************************************************/ var result = TradeAction.Unknown; var commandname = ""; foreach (var commandName in MainConfiguration.Configuration.Commands) { commandname = commandName; var command = GetCommand(commandname); if (command == null) { // in realtà dovrebbe incazzarsi di brutto continue; } result = command(market, result); // se il comando è Strong o hold allora termina subito if (result == TradeAction.Hold) { goto exitloop; } if (result == TradeAction.StrongBuy) { goto exitloop; } if (result == TradeAction.StrongSell) { goto exitloop; } //if (result == TradeAction.SellStopLoss) goto exitloop; } exitloop: /******************************************************************************** * LOGGING ********************************************************************************/ var e = Evaluations.EvaluationManager.Instance; var prediction = PredictionType.Unknown; switch (result) { //case TradeAction.SellStopLoss: // commandname += "--"; // prediction = PredictionType.LessThan; // break; case TradeAction.StrongBuy: commandname += "++ "; prediction = PredictionType.GreatherThan; break; case TradeAction.StrongSell: commandname += "-- "; prediction = PredictionType.LessThan; break; case TradeAction.Hold: commandname += "= "; prediction = PredictionType.Equal; break; case TradeAction.Buy: commandname += "+ "; prediction = PredictionType.GreatherThan; break; case TradeAction.Sell: commandname += "- "; prediction = PredictionType.LessThan; break; } AnalyticsTools.Call(commandname); var now = market.CandleMaker.CurrentCandleDate; var candleLen = MainConfiguration.Configuration.CandleWidthInSeconds / 60; e.Add(commandname, new Prediction() { Date = now, Type = prediction, Value = this.CoinValue }, candleLen); if (result != TradeAction.Hold) { LogTrade.Note += " " + commandname; } return(result); }
public override void Run() { var tests = new List <TestUnit>(); var testResultFileName = @"data\output\results" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".csv"; //TODO: caricare da configurazioni var testLoad = GetTestData(); //List<TestParam> testLoad = null; if (testLoad == null || testLoad.Count == 0) { testLoad = new List <TestParam>() { new TestParam(0, 0, 0, 0) }; } var e = Evaluations.EvaluationManager.Instance; foreach (var testParam in testLoad) { e.Clear(); /******************************************************************** * CONFIGURAZIONE *******************************************************************/ //MainConfiguration.Configuration = new Configuration(); //configuration; // MainConfiguration.Configuration = Configuration.BuildFromFile("global.json", "personal.json"); MainConfiguration.Configuration = Configuration.BuildFromDirectory(@"data/configuration"); MainConfiguration.Configuration.Init(); Configuration.SaveToFile(MainConfiguration.Configuration, @"data/configuration/serialized.result.json"); // chiama la configurazione Customize(testParam); /******************************************************************** * MANAGER *******************************************************************/ var manager = Manager.Builder.Create(MainConfiguration.Configuration.ManagerClass); if (manager == null) { throw new Exception("manager not configured"); } manager.Start(); if (MainConfiguration.Configuration.RealTimeHeartBeat && testLoad.Count == 1) { break; } System.Console.WriteLine(manager.Market.UniqueName); // salvo il risultato var test = new TestUnit() { Coins = manager.Market.TotCoins, Money = manager.Market.TotMoney, Coinvalue = manager.Market.Buy, Value = manager.Market.TotValue, Average = manager.Market.Average, MaxCoins = manager.Market.MaxCoins, MaxMoney = manager.Market.MaxMoney, MaxValue = manager.Market.MaxValue, Bids = manager.Market.TotBids, Ask = manager.Market.TotAsks, Gain = manager.Statistics.Gain, i = testParam.I, j = testParam.J, w = testParam.W, k = testParam.K }; /******************************************************************** * VISUALIZZAZIONE *******************************************************************/ // stampa il risultato test.Print(); if (test.Average > MainConfiguration.Configuration.StartWalletMoney) // deve esserci stato almeno un trade { if (test.Value > MainConfiguration.Configuration.StartWalletMoney) // devo aver guadagnato piu' di quanto ho investito { // salva il risultato se ci sono stati risultati incoraggianti CUtility.Log("*** GOOD"); tests.Add(test); /* * // scrive il risultato su csv * using (var log = new StreamWriter(testResultFileName, true)) * { * test.Print(log); * log.Flush(); * log.Close(); * } * */ // scrive il risultato con codice using (var log = new StreamWriter(testResultFileName + ".txt", true)) { test.PrintCode(log); log.Flush(); log.Close(); } // salvo la migliore configurazione var best = tests.OrderByDescending(o => o.Coins * o.Coinvalue + o.Money).FirstOrDefault(); if (best != null) { Configuration.SaveToFile(MainConfiguration.Configuration, @"data/configuration/best.result.json"); } var bestAvg = tests.OrderByDescending(o => o.Average).FirstOrDefault(); if (bestAvg != null) { Configuration.SaveToFile(MainConfiguration.Configuration, @"data/configuration/bestavg.result.json"); } } } AnalyticsTools.Print(); e.Finalize(); } /******************************************************************** * RISULTATI *******************************************************************/ if (MainConfiguration.Configuration.RealTimeHeartBeat && testLoad.Count == 1) { } else { // mostro la performance migliore CUtility.Log("*** BEST VALUE"); var firstOrDefault = tests.OrderByDescending(o => o.Coins * o.Coinvalue + o.Money).FirstOrDefault(); if (firstOrDefault != null) { firstOrDefault.Print(); } CUtility.Log("*** BEST AVERAGE"); var orDefault = tests.OrderByDescending(o => o.Average).FirstOrDefault(); if (orDefault != null) { orDefault.Print(); } } }