From 74855ba4b10e21c40c7dc4e3f45fae34b1c13385 Mon Sep 17 00:00:00 2001 From: "Luke I. Wilson" Date: Wed, 24 May 2023 16:31:13 -0500 Subject: [PATCH] Fixed Ichimoku bugs --- cmd/ichimoku.go | 38 +++++++++++++++++++++++++++----------- indicators.go | 4 ++-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/cmd/ichimoku.go b/cmd/ichimoku.go index d4163b8..5e7933b 100644 --- a/cmd/ichimoku.go +++ b/cmd/ichimoku.go @@ -34,6 +34,7 @@ func (s *IchimokuStrategy) Next(t *auto.Trader) { // - price closed above the cloud at the current time // - conversion above baseline // - future cloud must be green (LeadingA > LeadingB) + // - lagging span above lagging cloud // Oposite conditions for sell... @@ -52,18 +53,33 @@ func (s *IchimokuStrategy) Next(t *auto.Trader) { t.CloseOrdersAndPositions() } } else { + // v := a - b , then comparing v > 0 is the same as a > b + closeToLeadA := data.CloseIndex(now) - leadA.FloatIndex(now) + convToBase := conv.FloatIndex(now) - base.FloatIndex(now) + leadAToLeadB := leadA.FloatIndex(now) - leadB.FloatIndex(now) + futureLeadAToLeadB := leadA.Float(-1) - leadB.Float(-1) + laggingToLeadA := lagging.FloatIndex(*laggingTime) - leadA.FloatIndex(*laggingTime) + + // tw := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) + // fmt.Fprintf(tw, "closeToLeadA\t%v\n", closeToLeadA) + // fmt.Fprintf(tw, "convToBase\t%v\n", convToBase) + // fmt.Fprintf(tw, "leadAToLeadB\t%v\n", leadAToLeadB) + // fmt.Fprintf(tw, "futureLeadAToLeadB\t%v\n", futureLeadAToLeadB) + // fmt.Fprintf(tw, "laggingToLeadA\t%v\n\n", laggingToLeadA) + // tw.Flush() + // Look to enter a trade - if data.CloseIndex(now) > leadA.FloatIndex(now) && - leadA.FloatIndex(now) > leadB.FloatIndex(now) && - conv.FloatIndex(now) > base.FloatIndex(now) && - leadA.Float(-1) > leadB.Float(-1) && - lagging.FloatIndex(*laggingTime) > leadA.FloatIndex(*laggingTime) { + if closeToLeadA > 0 && + leadAToLeadB > 0 && + convToBase > 0 && + futureLeadAToLeadB > 0 && + laggingToLeadA > 0 { t.Buy(10000, 0, 0) - } else if data.CloseIndex(now) < leadA.FloatIndex(now) && - leadA.FloatIndex(now) < leadB.FloatIndex(now) && - conv.FloatIndex(now) < base.FloatIndex(now) && - leadA.Float(-1) < leadB.Float(-1) && - lagging.FloatIndex(*laggingTime) < leadA.FloatIndex(*laggingTime) { + } else if closeToLeadA < 0 && + leadAToLeadB < 0 && + convToBase < 0 && + futureLeadAToLeadB < 0 && + laggingToLeadA < 0 { t.Sell(10000, 0, 0) } } @@ -74,7 +90,7 @@ func main() { auto.Backtest(auto.NewTrader(auto.TraderConfig{ Broker: auto.NewTestBroker(broker, nil, 10000, 50, 0.0002, 0), Strategy: &IchimokuStrategy{convPeriod: 9, basePeriod: 26, leadingPeriods: 52}, - Symbol: "USD_JPY", + Symbol: "EUR_USD", Frequency: "M15", CandlesToKeep: 2500, })) diff --git a/indicators.go b/indicators.go index e083bae..6dc0056 100644 --- a/indicators.go +++ b/indicators.go @@ -54,9 +54,9 @@ func Ichimoku(price *IndexedFrame[UnixTime], convPeriod, basePeriod, leadingPeri conv := price.Highs().Copy().Rolling(convPeriod).Max().Add(price.Lows().Copy().Rolling(convPeriod).Min()).DivFloat(2) base := price.Highs().Copy().Rolling(basePeriod).Max().Add(price.Lows().Copy().Rolling(basePeriod).Min()).DivFloat(2) - lagging := price.Closes().Copy() leadingA := conv.Copy().Add(base).DivFloat(2) leadingB := price.Highs().Copy().Rolling(leadingPeriods).Max().Add(price.Lows().Copy().Rolling(leadingPeriods).Min()).DivFloat(2) + lagging := price.Closes().Copy() // Return a DataFrame of the results. return NewIndexedFrame( @@ -64,6 +64,6 @@ func Ichimoku(price *IndexedFrame[UnixTime], convPeriod, basePeriod, leadingPeri base.SetName("Base"), leadingA.SetName("LeadingA").ShiftIndex(leadingPeriods, UnixTimeStep(frequency)), leadingB.SetName("LeadingB").ShiftIndex(leadingPeriods, UnixTimeStep(frequency)), - lagging.SetName("Lagging").ShiftIndex(-leadingPeriods, UnixTimeStep(frequency)), + lagging.SetName("Lagging").ShiftIndex(-basePeriod, UnixTimeStep(frequency)), ) }