-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue13 candlestick trading strategy (#18)
Provides a simple trading automation that uses the candlestick trading strategy. The setup is Heroku-compliant and comes with support for MongoDB * #13 [INTERIM] Adds a basic candlestick pattern strategy implementation - Includes a simple test rig as part of the main application * #13 [INTERIM] - Allows strategies to leave no decision, if needed * #6 Adds a basic Heroku deployment file with MongoDB support * #6 Adds a basic Heroku deployment file with MongoDB support * #13 Keeps trade records after restart. Adds logging * #13 #16 Add params support to Poloniex's charting API - supports a starting and ending timestamp for now only - adds a few extension methods for converting dates to timestamps and timestamp calculations * #13 Fixes polling time interval * #13 #16 Adds various fixes related to time calculation * #11 Provides a price entry for every trade record * #13 Reverts the direction - Charting data from Poloniex comes in reverse chronological order * #13 Adds a unit test for checking the consistency of the Poloniex charting data * #13 Tests the potential of the candlestick pattern strategy -- NOTE: Use for manual testing only * #13 Redesigns basic candlestick pattern recognition - Assumes that the current candlestick is the one having a hammer shape, and thus prevents identifying a pattern too late - Adds a test rig with some real data * #3: Ignores data dump directory * #13 Extends the candlestick strategy test, adds a few helpers, and cleanup * #7 Updates the Kotlin version to 1.1.4
- Loading branch information
1 parent
5dc94d6
commit eeec586
Showing
23 changed files
with
1,467 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: java -Dserver.port=$PORT -Dspring.data.mongodb.uri=$MONGODB_URI $JAVA_OPTS -jar build/libs/*.jar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 79 additions & 1 deletion
80
src/main/kotlin/com/preslavrachev/cryptotrader/CryptotraderApplication.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/main/kotlin/com/preslavrachev/cryptotrader/extension/DateTimeExtensions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.preslavrachev.cryptotrader.extension | ||
|
||
import java.time.LocalDateTime | ||
|
||
fun LocalDateTime.toUnixTimestamp(): Long { | ||
return this.toEpochSecond(java.time.ZoneOffset.ofHours(2)) | ||
} | ||
|
||
fun Long.minusSecondPeriods(periods: Long, secondsInPeriod: Long): Long { | ||
val timePeriod = periods * secondsInPeriod | ||
assert(timePeriod <= this) { "The time period cannot exceed the current time!" } | ||
|
||
return this - timePeriod | ||
} |
18 changes: 17 additions & 1 deletion
18
src/main/kotlin/com/preslavrachev/cryptotrader/mvc/controller/DashboardController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,43 @@ | ||
package com.preslavrachev.cryptotrader.mvc.controller | ||
import com.preslavrachev.cryptotrader.extension.minusSecondPeriods | ||
import com.preslavrachev.cryptotrader.extension.toUnixTimestamp | ||
import com.preslavrachev.cryptotrader.mvc.model.Order | ||
import com.preslavrachev.cryptotrader.session.AppSession | ||
import org.springframework.stereotype.Controller | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RequestMethod | ||
import org.springframework.web.bind.annotation.ResponseBody | ||
import remote.poloniex.service.PoloniexApiService | ||
import java.time.LocalDateTime | ||
import javax.inject.Inject | ||
|
||
@Controller | ||
@RequestMapping("/") | ||
class DashboardController { | ||
|
||
@Inject | ||
lateinit var session:AppSession | ||
|
||
@Inject | ||
lateinit var poloniexApiService: PoloniexApiService | ||
|
||
@RequestMapping("hello", method = arrayOf(RequestMethod.GET)) | ||
@ResponseBody | ||
fun hello(): PoloniexApiService.ChartDataEntryList { | ||
return poloniexApiService.getChartData() | ||
val end = LocalDateTime.now().toUnixTimestamp() | ||
val start = end.minusSecondPeriods(100, 300) | ||
return poloniexApiService.getChartData(start = start, end = end) | ||
} | ||
|
||
@RequestMapping("balances", method = arrayOf(RequestMethod.GET)) | ||
@ResponseBody | ||
fun returnBalances(): Any { | ||
return poloniexApiService.returnBalances() | ||
} | ||
|
||
@RequestMapping("orders", method = arrayOf(RequestMethod.GET)) | ||
@ResponseBody | ||
fun orders(): List<Order> { | ||
return session.orders | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
src/main/kotlin/com/preslavrachev/cryptotrader/session/PackageMarker.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.preslavrachev.cryptotrader.session | ||
|
||
class PackageMarker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
src/main/kotlin/com/preslavrachev/cryptotrader/trading/instrument/timeline/TimelineNode.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.preslavrachev.cryptotrader.trading.instrument.timeline | ||
|
||
import java.time.LocalDateTime | ||
|
||
data class TimelineNode<out T>( | ||
val time: LocalDateTime, | ||
val content: T | ||
) |
7 changes: 7 additions & 0 deletions
7
src/main/kotlin/com/preslavrachev/cryptotrader/trading/strategy/TradingStrategy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.preslavrachev.cryptotrader.trading.strategy | ||
|
||
import com.preslavrachev.cryptotrader.trading.instrument.timeline.TimelineNode | ||
|
||
interface TradingStrategy<in T> { | ||
fun decide(input: List<TimelineNode<T>>): TradingStrategyDecisionEnum | ||
} |
7 changes: 7 additions & 0 deletions
7
...ain/kotlin/com/preslavrachev/cryptotrader/trading/strategy/TradingStrategyDecisionEnum.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.preslavrachev.cryptotrader.trading.strategy | ||
|
||
enum class TradingStrategyDecisionEnum { | ||
BUY, | ||
SELL, | ||
NO_DECISION | ||
} |
37 changes: 37 additions & 0 deletions
37
...com/preslavrachev/cryptotrader/trading/strategy/impl/CandlestickPatternTradingStrategy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.preslavrachev.cryptotrader.trading.strategy.impl | ||
|
||
import com.preslavrachev.cryptotrader.trading.instrument.candlestick.Candlestick | ||
import com.preslavrachev.cryptotrader.trading.instrument.candlestick.CandlestickPatternEnum | ||
import com.preslavrachev.cryptotrader.trading.instrument.timeline.TimelineNode | ||
import com.preslavrachev.cryptotrader.trading.strategy.TradingStrategy | ||
import com.preslavrachev.cryptotrader.trading.strategy.TradingStrategyDecisionEnum | ||
import java.util.* | ||
import java.util.logging.Logger | ||
|
||
class CandlestickPatternTradingStrategy : TradingStrategy<Candlestick> { | ||
|
||
companion object { | ||
val LOGGER = Logger.getLogger(CandlestickPatternTradingStrategy::class.simpleName) | ||
|
||
// TODO: move this knowledge over to the candlestick patterns enum | ||
val BOOLISH_PATTERNS = EnumSet.of(CandlestickPatternEnum.HAMMER, CandlestickPatternEnum.INVERTED_HAMMER) | ||
val BEARISH_PATTERNS = EnumSet.of(CandlestickPatternEnum.SHOOTING_STAR, CandlestickPatternEnum.HANGING_MAN) | ||
} | ||
|
||
override fun decide(input: List<TimelineNode<Candlestick>>): TradingStrategyDecisionEnum { | ||
assert(input.size >= 2) { LOGGER.warning("The input must have at least two data points!") } | ||
|
||
val prev = input[input.lastIndex - 1] | ||
val current = input[input.lastIndex] | ||
|
||
val pattern = CandlestickPatternEnum.evaluate(prev.content, current.content) | ||
|
||
if (pattern.any { BOOLISH_PATTERNS.contains(it) }) { | ||
return TradingStrategyDecisionEnum.BUY | ||
} else if (pattern.any { BEARISH_PATTERNS.contains(it) }) { | ||
return TradingStrategyDecisionEnum.SELL | ||
} else { | ||
return TradingStrategyDecisionEnum.NO_DECISION | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
src/test/kotlin/com/preslavrachev/cryptotrader/extension/Collection.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.preslavrachev.cryptotrader.extension | ||
|
||
fun <T> List<T>.toPairs(): List<Pair<T,T>> { | ||
val leftSide = this.dropLast(1) | ||
val rightSide = this.drop(1) | ||
return leftSide.zip(rightSide) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.