Skip to content

Commit

Permalink
Tidying up strategies, building a lock and draft section. Started wor…
Browse files Browse the repository at this point in the history
…king on momentum
  • Loading branch information
mccaffers committed Feb 3, 2024
1 parent 9b3f3d6 commit 346dc32
Show file tree
Hide file tree
Showing 17 changed files with 568 additions and 1 deletion.
2 changes: 1 addition & 1 deletion scripts/backtestings/aws.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ main() {

######################################
### EXPERIMENT DEFINITION
source $my_dir/experiments/random-hh-ll/indices/range
source $my_dir/experiments/momentum/indices/fixed
######################################

# Remove binary files & tests
Expand Down
18 changes: 18 additions & 0 deletions scripts/backtestings/experiments/momentum/forex/fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
declare -a strategies=("Momentum_4d991e3b")
declare -a symbolsArray=("EURUSD" "USDJPY" "GBPUSD" "NZDUSD" "USDCHF" "USDCAD" "AUDUSD")

# Forex from 2004
yearsStart=2018
yearsEnd=2023

# These don't mean anything in RandomHHLL as the SL/TP is defined by the highest and lowest value from the last time period
stopLossInPipsRange="200 1 200" # STOP LOSS Distance in PIPs
limitInPipsRange="200 1 200" # TAKE PROFIT Distance in PIPs

# Account Equity
accountEquity=10000
maximumDrawndownPercentage=75
fasterProcessingBySkippingSomeTickData=true

# Strategy Variables
randomStrategyAmountOfHHLLSseq="5 5 15"
20 changes: 20 additions & 0 deletions scripts/backtestings/experiments/momentum/indices/fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
declare -a strategies=("Momentum_4d991e3b")

## Multiple Indexes
declare -a symbolsArray=("JPNIDXJPY" "ESPIDXEUR" "FRAIDXEUR" "DEUIDXEUR" "AUSIDXAUD" "USATECHIDXUSD" "USA500IDXUSD" "USA30IDXUSD" "EUSIDXEUR" "GBRIDXGBP")

# Forex from 2004
yearsStart=2018
yearsEnd=2023

# These don't mean anything in RandomHHLL as the SL/TP is defined by the highest and lowest value from the last time period
stopLossInPipsRange="200 1 200" # STOP LOSS Distance in PIPs
limitInPipsRange="200 1 200" # TAKE PROFIT Distance in PIPs

# Account Equity
accountEquity=10000
maximumDrawndownPercentage=75
fasterProcessingBySkippingSomeTickData=true

# Strategy Variables
randomStrategyAmountOfHHLLSseq="5 5 15"
21 changes: 21 additions & 0 deletions scripts/backtestings/experiments/random-hh-ll/bonds/range
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
declare -a strategies=("RandomRecentHighLow")

declare -a symbolsArray=("BUNDTREUR" "UKGILTTRGBP" "USTBONDTRUSD")

# Forex from 2004
yearsStart=2020
yearsEnd=2023

# These don't mean anything in RandomHHLL as the SL/TP is defined by the highest and lowest value from the last time period
stopLossInPipsRange="200 1 200" # STOP LOSS Distance in PIPs
limitInPipsRange="200 1 200" # TAKE PROFIT Distance in PIPs

# Account Equity
accountEquity=10000
maximumDrawndownPercentage=75
fasterProcessingBySkippingSomeTickData=true

# Strategy Variables
randomStrategyAmountOfHHLLSseq="4 2 10"
#RANDOMHHLL_HOURS_TO_KEEP=5
#RANDOMHHLL_TP_LOOKBACK_OVER_HOURS=2
22 changes: 22 additions & 0 deletions scripts/backtestings/experiments/random-hh-ll/crypto/range
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
declare -a strategies=("RandomRecentHighLow")

## Crypto
declare -a symbolsArray=("ETHUSD" "BTCUSD")

# Forex from 2004
yearsStart=2018
yearsEnd=2023

# These don't mean anything in RandomHHLL as the SL/TP is defined by the highest and lowest value from the last time period
stopLossInPipsRange="200 1 200" # STOP LOSS Distance in PIPs
limitInPipsRange="200 1 200" # TAKE PROFIT Distance in PIPs

# Account Equity
accountEquity=10000
maximumDrawndownPercentage=75
fasterProcessingBySkippingSomeTickData=true

# Strategy Variables
randomStrategyAmountOfHHLLSseq="4 2 10"
#RANDOMHHLL_HOURS_TO_KEEP=5
#RANDOMHHLL_TP_LOOKBACK_OVER_HOURS=2
1 change: 1 addition & 0 deletions src/backtesting/Analysis/Reporting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public void EndOfRunReport(string reason = "")
stopDistanceInPips = decimal.Parse(envVariables.stopDistanceInPips),
limitDistanceInPips = decimal.Parse(envVariables.limitDistanceInPips),
instanceCount = envVariables.instanceCount,
randomHHLLValue = envVariables.randomStrategyAmountOfHHLL
};


Expand Down
1 change: 1 addition & 0 deletions src/backtesting/Utilities/ReportObj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class ReportFinalObj {
public decimal limitDistanceInPips {get;set;}

public int instanceCount { get;set; }
public decimal randomHHLLValue {get;set;}

public IEnvironmentVariables? environmentVariables {get;set;}
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
96 changes: 96 additions & 0 deletions src/strategies/locked/Momentum/Momentum_14a2da93.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System.Diagnostics.CodeAnalysis;
using backtesting_engine;
using backtesting_engine.interfaces;
using backtesting_engine_models;
using Utilities;

namespace backtesting_engine_strategies;

public class Momentum_14a2da93: BaseStrategy, IStrategy
{
private List<OhlcObject> ohlcList = new List<OhlcObject>();

public Momentum_14a2da93(IRequestOpenTrade requestOpenTrade, IEnvironmentVariables envVariables, ITradingObjects tradeObjs, ICloseOrder closeOrder, IWebNotification webNotification) : base(requestOpenTrade, tradeObjs, envVariables, closeOrder, webNotification) { }

private OhlcObject lastItem = new OhlcObject();

private DateTime lastTraded = DateTime.MinValue;

[SuppressMessage("Sonar Code Smell", "S2245:Using pseudorandom number generators (PRNGs) is security-sensitive", Justification = "Random function has no security use")]
public async Task Invoke(PriceObj priceObj)
{

ohlcList = GenericOhlc.CalculateOHLC(priceObj, priceObj.ask, TimeSpan.FromMinutes(120), ohlcList);

// Maximum of one trade open at a time
// Conditional to only invoke the strategy if there are no trades open
if (tradeObjs.openTrades.Count() >= 1)
{
return;
}

if(priceObj.date.Subtract(lastTraded).TotalHours < 8){
return;
}


// Keep 5 hours of history (30*10)
// Only start trading once you have 5 hours
if (ohlcList.Count > envVariables.randomStrategyAmountOfHHLL)
{

lastTraded=priceObj.date;

// Get the highest value from all of the OHLC objects
var distance = (ohlcList.Last().close - ohlcList.First().close) * envVariables.GetScalingFactor(priceObj.symbol);
var speed = distance / (120*envVariables.randomStrategyAmountOfHHLL);

// System.Console.WriteLine(speed);

// Too slow
if(Math.Abs(speed) < 1m){
return;
}

var direction = TradeDirection.BUY;
if(speed > 0){
direction = TradeDirection.SELL;
}

var stopLevel = direction == TradeDirection.BUY ? ohlcList.Min(x => x.low) :
ohlcList.Max(x => x.high);

var limitLevel = direction == TradeDirection.BUY ? ohlcList.TakeLast(2).Average(x => x.close):
ohlcList.TakeLast(2).Average(x => x.close);

var stopDistance = direction == TradeDirection.SELL ? (stopLevel - priceObj.bid) : (priceObj.ask - stopLevel);
stopDistance = stopDistance * envVariables.GetScalingFactor(priceObj.symbol);

var limitDistance = direction == TradeDirection.BUY ? (limitLevel - priceObj.bid) : (priceObj.ask - limitLevel);
limitDistance = limitDistance * envVariables.GetScalingFactor(priceObj.symbol);

if (stopDistance < 10 || limitDistance < 2)
{
return;
}

var key = DictionaryKeyStrings.OpenTrade(priceObj.symbol, priceObj.date);

var openOrderRequest = new RequestObject(priceObj, direction, envVariables, key)
{
size = decimal.Parse(envVariables.tradingSize),
stopDistancePips = stopDistance,
limitDistancePips = limitDistance
};

this.requestOpenTrade.Request(openOrderRequest);

ohlcList.RemoveAt(0);
}

// Surpress CS1998
// Async method lacks 'await' operators and will run synchronously
await Task.CompletedTask;

}
}
100 changes: 100 additions & 0 deletions src/strategies/locked/Momentum/Momentum_18d834cc.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System.Diagnostics.CodeAnalysis;
using backtesting_engine;
using backtesting_engine.interfaces;
using backtesting_engine_models;
using Utilities;

namespace backtesting_engine_strategies;

public class Momentum_18d834cc : BaseStrategy, IStrategy
{
private List<OhlcObject> ohlcList = new List<OhlcObject>();

public Momentum_18d834cc(IRequestOpenTrade requestOpenTrade, IEnvironmentVariables envVariables, ITradingObjects tradeObjs, ICloseOrder closeOrder, IWebNotification webNotification) : base(requestOpenTrade, tradeObjs, envVariables, closeOrder, webNotification) { }

private OhlcObject lastItem = new OhlcObject();

private DateTime lastTraded = DateTime.MinValue;

[SuppressMessage("Sonar Code Smell", "S2245:Using pseudorandom number generators (PRNGs) is security-sensitive", Justification = "Random function has no security use")]
public async Task Invoke(PriceObj priceObj)
{

ohlcList = GenericOhlc.CalculateOHLC(priceObj, priceObj.ask, TimeSpan.FromMinutes(30), ohlcList);

// Maximum of one trade open at a time
// Conditional to only invoke the strategy if there are no trades open
if (tradeObjs.openTrades.Count() >= 1)
{
return;
}

if(priceObj.date.Subtract(lastTraded).TotalHours < 8){
return;
}


// Keep 5 hours of history (30*10)
// Only start trading once you have 5 hours
if (ohlcList.Count > envVariables.randomStrategyAmountOfHHLL)
{

lastTraded=priceObj.date;

// Get the highest value from all of the OHLC objects
var distance = (ohlcList.Last().close - ohlcList.First().close) * envVariables.GetScalingFactor(priceObj.symbol);
var speed = distance / (30 * envVariables.randomStrategyAmountOfHHLL);

// System.Console.WriteLine(speed);

// Too slow
if(Math.Abs(speed) < 1m){
return;
}

var direction = TradeDirection.BUY;
if(speed > 0){
direction = TradeDirection.SELL;
}

var stopLevel = direction == TradeDirection.BUY ? ohlcList.Min(x => x.low) :
ohlcList.Max(x => x.high);

var limitLevel = direction == TradeDirection.BUY ? ohlcList.TakeLast(2).Average(x => x.close):
ohlcList.TakeLast(2).Average(x => x.close);

var stopDistance = direction == TradeDirection.SELL ? (stopLevel - priceObj.bid) : (priceObj.ask - stopLevel);
stopDistance = stopDistance * envVariables.GetScalingFactor(priceObj.symbol);

var limitDistance = direction == TradeDirection.BUY ? (limitLevel - priceObj.bid) : (priceObj.ask - limitLevel);
limitDistance = limitDistance * envVariables.GetScalingFactor(priceObj.symbol);

if (stopDistance < 10 || limitDistance < 2)
{
return;
}

if(stopDistance > 100){
stopDistance = 100;
}

var key = DictionaryKeyStrings.OpenTrade(priceObj.symbol, priceObj.date);

var openOrderRequest = new RequestObject(priceObj, direction, envVariables, key)
{
size = decimal.Parse(envVariables.tradingSize),
stopDistancePips = stopDistance,
limitDistancePips = limitDistance
};

this.requestOpenTrade.Request(openOrderRequest);

ohlcList.RemoveAt(0);
}

// Surpress CS1998
// Async method lacks 'await' operators and will run synchronously
await Task.CompletedTask;

}
}
Loading

0 comments on commit 346dc32

Please sign in to comment.