<commit_before>package org.nikosoft.oanda.bot.scalpers

import akka.actor.Actor
import org.nikosoft.oanda.api.ApiModel.PricingModel.Price
import org.nikosoft.oanda.instruments.Model.{CandleStick, Chart, MACDCandleCloseIndicator, StochasticCandleIndicator}
import org.nikosoft.oanda.instruments.Oscillators.MACDItem

object MACDScalperActor {

  trait OpenPosition

  case object OpenShortPosition extends OpenPosition

  case object OpenLongPosition extends OpenPosition

  case object DoNothing extends OpenPosition

  case class TrainingStatistics(profitPips: Int = 0, lossPips: Int = 0)

}

class MACDScalperActor(chart: Chart) extends Actor {

  import MACDScalperActor._

  var allCandles: Seq[CandleStick] = Seq.empty

  def receive: Receive = {
    case candles: Seq[CandleStick] =>
      candles.reverse.foldLeft((Seq.empty[CandleStick], Option.empty[CandleStick], TrainingStatistics())) {
        case ((historicalCandles, None), candle) =>
          val toppedUpHistoricalCandles = candle +: historicalCandles
          considerOpeningPosition(toppedUpHistoricalCandles) match {
            case Some(OpenLongPosition) =>
              val openedAt = Some(candle)
              (toppedUpHistoricalCandles, openedAt)
            case _ => (toppedUpHistoricalCandles, None)
          }
        case ((historicalCandles, openedAtOption @ Some(openedAt)), candle) =>
          val toppedUpHistoricalCandles = candle +: historicalCandles
          if (considerClosingPosition(toppedUpHistoricalCandles)) {
            println(s"opened position at ${openedAt.time}, closed at ${candle.time}, ${candle.close - openedAt.close}")
            (toppedUpHistoricalCandles, None)
          } else (toppedUpHistoricalCandles, openedAtOption)
      }

    case candle: CandleStick =>

    case price: Price =>

  }

  def considerOpeningPosition(lastCandles: Seq[CandleStick]): Option[OpenPosition] = for {
    candle <- lastCandles.headOption
    previousCandle <- lastCandles.tail.headOption
    macd <- candle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    macdHistogram <- macd.histogram
    prevMacd <- previousCandle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    prevMacdHistogram <- prevMacd.histogram
    stochastic <- candle.indicator[StochasticCandleIndicator, BigDecimal]("5_3_3")
  } yield {
    if (prevMacdHistogram < 0 && macdHistogram > 0) OpenLongPosition
    else DoNothing
  }

  def considerClosingPosition(lastCandles: Seq[CandleStick]): Boolean = (for {
    candle <- lastCandles.headOption
    previousCandle <- lastCandles.tail.headOption
    macd <- candle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    macdHistogram <- macd.histogram
    prevMacd <- previousCandle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    prevMacdHistogram <- prevMacd.histogram
  } yield {
    if (macdHistogram < 0 && prevMacdHistogram > 0) true
    else false
  }).getOrElse(false)
}
<commit_msg>interesting result with stochastic oscillator Profit 1845, loss 550, diff 1295<commit_after>package org.nikosoft.oanda.bot.scalpers

import akka.actor.Actor
import org.nikosoft.oanda.api.ApiModel.PricingModel.Price
import org.nikosoft.oanda.instruments.Model.{CandleStick, Chart, MACDCandleCloseIndicator, StochasticCandleIndicator}
import org.nikosoft.oanda.instruments.Oscillators.MACDItem
import scalaz.Scalaz._

object MACDScalperActor {

  trait OpenPosition

  case object OpenShortPosition extends OpenPosition

  case object OpenLongPosition extends OpenPosition

  case object DoNothing extends OpenPosition

  case class TrainingStatistics(profitPips: Int = 0, lossPips: Int = 0)

}

class MACDScalperActor(chart: Chart) extends Actor {

  import MACDScalperActor._

  var allCandles: Seq[CandleStick] = Seq.empty

  def receive: Receive = {
    case candles: Seq[CandleStick] =>
      val (_, _, stats) = candles.reverse.foldLeft((Seq.empty[CandleStick], Option.empty[CandleStick], TrainingStatistics())) {
        case ((historicalCandles, None, _stats), candle) =>
          val toppedUpHistoricalCandles = candle +: historicalCandles
          considerOpeningPosition(toppedUpHistoricalCandles) match {
            case Some(OpenLongPosition) =>
              val openedAt = Some(candle)
              (toppedUpHistoricalCandles, openedAt, _stats)
            case _ => (toppedUpHistoricalCandles, None, _stats)
          }
        case ((historicalCandles, openedAtOption@Some(openedAt), _stats), candle) =>
          val toppedUpHistoricalCandles = candle +: historicalCandles
          if (considerClosingPosition(toppedUpHistoricalCandles)) {
            val trade = ((candle.close - openedAt.close) * 100000).toInt
            println(s"opened position at ${openedAt.time}, closed at ${candle.time}, ${candle.close - openedAt.close}")
            val profitPips = (trade > 0) ? (_stats.profitPips + trade) | _stats.profitPips
            val lossPips = (trade < 0) ? (_stats.lossPips + (-trade)) | _stats.lossPips
            (toppedUpHistoricalCandles, None, _stats.copy(profitPips = profitPips, lossPips))
          } else (toppedUpHistoricalCandles, openedAtOption, _stats)
      }

      println(s"Profit ${stats.profitPips}, loss ${stats.lossPips}, diff ${stats.profitPips - stats.lossPips}")

    case candle: CandleStick =>

    case price: Price =>

  }

  def considerOpeningPosition(lastCandles: Seq[CandleStick]): Option[OpenPosition] = for {
    candle <- lastCandles.headOption
    previousCandle <- lastCandles.tail.headOption
    macd <- candle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    macdHistogram <- macd.histogram
    prevMacd <- previousCandle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    prevMacdHistogram <- prevMacd.histogram
    stochastic <- candle.indicator[StochasticCandleIndicator, BigDecimal]("5_3_3")
  } yield {
    if (
      macdHistogram < 0 &&
//      macdHistogram > prevMacdHistogram &&
      stochastic < 10
    ) OpenLongPosition
    else DoNothing
  }

  def considerClosingPosition(lastCandles: Seq[CandleStick]): Boolean = (for {
    candle <- lastCandles.headOption
    previousCandle <- lastCandles.tail.headOption
    macd <- candle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    macdHistogram <- macd.histogram
    prevMacd <- previousCandle.indicator[MACDCandleCloseIndicator, MACDItem](None)
    prevMacdHistogram <- prevMacd.histogram
    stochastic <- candle.indicator[StochasticCandleIndicator, BigDecimal]("5_3_3")
  } yield {
//    if (macdHistogram > 0 && prevMacdHistogram < 0) true
    if (
      macdHistogram > 0 &&
      stochastic > 90
    ) true
    else false
  }).getOrElse(false)
}

{'fraction_non_alphanumeric': 0.09559710494571773, 'fraction_numerical': 0.0066344993968636915, 'mean_word_length': 3.8629032258064515, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '379660', 'n_tokens_mistral': 2225, 'n_tokens_neox': 2036, 'n_words': 400}