Hi QuantConnect Community,
If someone had some free time to see what I am doing wrong here lol. I created a class Pair for my junk I want to pass off to invidivual currencies in the basket. I pass off setting the Fibo Pivot Points when I use later as a stop loss.
USDCHF.UpdateFiboPP(getHistory("USDCHF"));
And then when I open my trade in OpenTrade() My price is sometimes past that point from when I created my fibo PP. I don't think it should be that way and can't see where I screwed up or if it just isn't how I expect the schedule works?
Below are the main.cs and Pair.cs for my project. I didn't know how to make it public to where I could just link the link and you all could clone?
main.cs
namespace QuantConnect
{
/*
* Basic Template Algorithm
*
* The underlying QCAlgorithm class has many methods which enable you to use QuantConnect.
* We have explained some of these here, but the full base class can be found at:
* https://github.com/QuantConnect/Lean/tree/master/Algorithm
*/
public class TMMSystemAlgo : QCAlgorithm
{
private string _lotSize = "Normal"; //Normal, Half, Double
private decimal _units = 1M;
private int _lookBackHours = 120;
private static decimal defaultRisk = 0.01M;
//initialize currencies
public decimal risk = 0.01M; //1%
public decimal previousTotalProfit = 0;
public decimal currentTotalProfit = 0;
public bool wereWeProfitable = true;
//public Pair EURUSD = new Pair("EURUSD",120);
public Pair USDCHF = new Pair("USDCHF",120);
//public Pair USDJPY = new Pair("USDJPY",120);
//public Pair CADUSD = new Pair("CADUSD",120);
//public Pair GBPUSD = new Pair("GBPUSD",120);
//public Pair AUDUSD = new Pair("AUDUSD",120);
//public Pair NZDUSD = new Pair("NZDUSD",120);
/*
public decimal highestHigh = -10000;
public decimal lowestLow = 10000;
public decimal close = 1;
*/
public override void Initialize()
{
// backtest parameters
SetStartDate(2017, 05, 01);
SetEndDate(DateTime.Now);
// cash allocation
SetCash(4000);
// request specific equities
// including forex. Options and futures in beta.
//AddEquity("SPY", Resolution.Minute);
//AddForex("EURUSD", Resolution.Minute);
AddForex("USDCHF", Resolution.Minute, Market.Oanda);
//AddForex("USDJPY", Resolution.Minute, Market.Oanda);
//AddForex("CADUSD", Resolution.Minute, Market.Oanda);
//AddForex("GBPUSD", Resolution.Minute, Market.Oanda);
//AddForex("EURUSD", Resolution.Minute, Market.Oanda);
//AddForex("AUDUSD", Resolution.Minute, Market.Oanda);
//AddForex("NZDUSD", Resolution.Minute, Market.Oanda);
//Schedule to get HLC of previous day Forex Data in EST I think
Schedule.On(DateRules.Every(DayOfWeek.Tuesday,DayOfWeek.Wednesday,DayOfWeek.Thursday,DayOfWeek.Friday), TimeRules.At(01,00), () =>
{
//Start of Every new day 6Am GMT get fibo pivots from previous day.
USDCHF.UpdateFiboPP(getHistory("USDCHF"));
//USDJPY.UpdateFiboPP(getHistory("USDJPY"));
//CADUSD.UpdateFiboPP(getHistory("CADUSD"));
//GBPUSD.UpdateFiboPP(getHistory("GBPUSD"));
//EURUSD.UpdateFiboPP(getHistory("EURUSD"));
//AUDUSD.UpdateFiboPP(getHistory("AUDUSD"));
//NZDUSD.UpdateFiboPP(getHistory("NZDUSD"));
//Calculate new Trend direction basket and trade only those currencies.
USDCHF.UpdateScore(getHistory("USDCHF"));
//USDJPY.UpdateScore(getHistory("USDJPY"));
//CADUSD.UpdateScore(getHistory("CADUSD"));
//GBPUSD.UpdateScore(getHistory("GBPUSD"));
//EURUSD.UpdateScore(getHistory("EURUSD"));
//AUDUSD.UpdateScore(getHistory("AUDUSD"));
//NZDUSD.UpdateScore(getHistory("NZDUSD"));
//Open Up trades
OpenTrades();
});
Schedule.On(DateRules.Every(DayOfWeek.Monday,DayOfWeek.Tuesday,DayOfWeek.Wednesday,DayOfWeek.Thursday,DayOfWeek.Friday), TimeRules.At(15,00), () =>
{
//Liquidate any open trades.
Liquidate("USDCHF");
});
}
public void OpenTrades(){
//Account Risk / Trade Risk Pips x pip value = Position Size * 10000
//Exchange rate is quote if USD is first if second then it is 1
//(4000 * .01)/45 / exchange rate = x * 10000
decimal accountBalance = 4000;
//Set Risk and check if we were profitable
//Compare if we were profitable today
previousTotalProfit = currentTotalProfit;
currentTotalProfit = Portfolio.TotalProfit;
//Debug(currentTotalProfit.ToString());
if(currentTotalProfit > previousTotalProfit){
wereWeProfitable = true;
}
else if (currentTotalProfit < previousTotalProfit){
wereWeProfitable = false;
}
if(currentTotalProfit == previousTotalProfit){
wereWeProfitable = wereWeProfitable;
}
//Debug(wereWeProfitable.ToString());
//If trend direction changes double lotsize
//If we were not half lotsize if we were go back to default
if(!wereWeProfitable){
//risk*=0.5M;
}
else{
risk = defaultRisk;
}
//Setup SL variable for use
decimal SL = 0.0M;
//USDCHF
int score = USDCHF.score;
decimal price = Securities["USDCHF"].Price;
//if positive score go long if negative go short 0 stay out.
if(USDCHF.score > 0M && USDCHF.score < 5) {
//SL
if(BandContract(USDCHF)){
SL = USDCHF.S3;
}else {
SL = USDCHF.S2;
}
if(SL>price){
Debug("WRONG");
Debug("Close: " + USDCHF.close.ToString());
}
Debug("Long SL: " + SL.ToString());
Debug("Long Price: " + price.ToString());
//Open Long
_units = Math.Round((((accountBalance * risk) / ((price - SL)))/price),0);
if(_units <= 0) _units = 1;
MarketOrder("USDCHF", _units, asynchronous: true);
StopMarketOrder("USDCHF", _units * -1, SL);
//LimitOrder("USDCHF", _units * -1, USDCHF.S2);
}else if(USDCHF.score < 0M && USDCHF.score > -5){
if(BandContract(USDCHF)){
SL = USDCHF.R3;
}else {
SL = USDCHF.R2;
}
if(SL < price){
Debug("WRONG");
Debug("Close: " + USDCHF.close.ToString());
}
Debug("Short SL: " + SL.ToString());
Debug("Short Price: " + price.ToString());
//Open Short
_units = Math.Round((((accountBalance * risk) / ((SL - price)))/price),0);
if(_units <= 0) _units = 1;
MarketOrder("USDCHF", _units*-1, asynchronous: true);
StopMarketOrder("USDCHF", _units, SL);
//LimitOrder("USDCHF", _units, USDCHF.R2);
}
Debug("R3: "+ USDCHF.R3.ToString());
Debug("R2: "+ USDCHF.R2.ToString());
Debug("R1: "+ USDCHF.R1.ToString());
Debug("PP: "+ USDCHF.PP.ToString());
Debug("S1: "+ USDCHF.S1.ToString());
Debug("S2: "+ USDCHF.S2.ToString());
Debug("S3: "+ USDCHF.S3.ToString());
//USDJPY
//CADUSD
//GBPUSD
//EURUSD
//AUDUSD
//NZDUSD
}
public bool BandContract(Pair symbol){
//Any Resistance Contracted?
bool resContract = false;
bool supContract = false;
if(symbol.R1<symbol.oldR1){
resContract = true;
}
if(symbol.R2<symbol.oldR2){
resContract = true;
}
if(symbol.R3<symbol.oldR3){
resContract = true;
}
if(symbol.S1>symbol.oldS1){
supContract = true;
}
if(symbol.S2>symbol.oldS2){
supContract = true;
}
if(symbol.S3>symbol.oldS3){
supContract = true;
}
if(supContract && resContract){
return(true);
}
return(false);
}
public IEnumerable getHistory(string symbol){
var quoteBarHistory = History<QuoteBar>(symbol, _lookBackHours, Resolution.Hour);
return quoteBarHistory;
}
/*
* New data arrives here.
* The "Slice" data represents a slice of time, it has all the data you need for a moment.
*/
public override void OnData(Slice data)
{
// slice has lots of useful information
TradeBars bars = data.Bars;
Ticks ticks = data.Ticks;
//Check current price and if >< TP update stop order. With PP to
//Splits splits = data.Splits;
//Dividends dividends = data.Dividends;
//If this tick goes past S1 R1 in profit start Trail stop from pp.
//Get just this bar.
TradeBar bar;
if (bars.ContainsKey("EURUSD")) bar = bars["EURUSD"];
if (!Portfolio.HoldStock)
{
// place an order, positive is long, negative is short.
// Order("SPY", quantity);
// or request a fixed fraction of a specific asset.
// +1 = 100% long. -2 = short all capital with 2x leverage.
//SetHoldings("EURUSD", 1, true);
// debug message to your console. Time is the algorithm time.
// send longer messages to a file - these are capped to 10kb
//Debug("Purchased USDCHF on " + Time.ToShortDateString());
//Log("This is a longer message send to log.");
/*
var quoteBarHistory = History<QuoteBar>("EURUSD", 1440, Resolution.Minute);
foreach (QuoteBar quoteBar in quoteBarHistory)
{
if (quoteBar.High > highestHigh) highestHigh = quoteBar.High;
if (quoteBar.Low < lowestLow) lowestLow = quoteBar.Low;
//if (tradeBar.EndTime > oldestTime) close = tradeBar.Close;
//spyDailySma.Update(tradeBar.EndTime, tradeBar.Close);
}
Debug("High " + highestHigh.ToString());
Debug("Low " + lowestLow.ToString());
*/
}
}
}
}
Pair.cs
namespace QuantConnect {
//
// Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
// files use "public partial class" if you want to split up your algorithm namespace into multiple files.
//
public partial class Pair : QCAlgorithm, IAlgorithm
{
private string sym;
private int _c;
private int _lookBackHours;
private static int hoursInADay = 24;
private int[] _states = new int[29];
private int[] _scenerios = new int[17];
private decimal[] _dayChange = new decimal[21];
private decimal _average;
public decimal highestHigh, oldhighestHigh;
public decimal lowestLow, oldlowestLow;
public decimal close, oldclose, open;
public decimal days2, days3, days4, days5;
public decimal day1Change, day2Change, day3Change, day4Change, day5Change;
public DateTime oldestTime, oldoldestTime;
public int score,oldScore;
public decimal PP, S1, S2, S3, R1, R2, R3, oldPP, oldS1, oldS2, oldS3, oldR1, oldR2, oldR3;
public Pair(string symbol, int lookBackHours){
sym = symbol;
_lookBackHours = lookBackHours;
score = 0;
oldScore = 0;
}
public void UpdateFiboPP(IEnumerable quoteBarHistory){
//Get Previous Bars and go through them for High Low and close
highestHigh = -10000;
lowestLow = 10000;
close = 1;
oldhighestHigh = -10000;
oldlowestLow = 10000;
oldclose = 1;
_c = _lookBackHours;
foreach (QuoteBar quoteBar in quoteBarHistory)
{
if(_c <= _lookBackHours && _c > _lookBackHours - hoursInADay){
if (quoteBar.High > highestHigh) highestHigh = quoteBar.High;
if (quoteBar.Low < lowestLow) lowestLow = quoteBar.Low;
if(_c == 120) close = quoteBar.Close;
}
if(_c <= _lookBackHours - hoursInADay && _c > _lookBackHours - (hoursInADay*2) ){
if (quoteBar.High > oldhighestHigh) oldhighestHigh = quoteBar.High;
if (quoteBar.Low < oldlowestLow) oldlowestLow = quoteBar.Low;
if(_c == _lookBackHours - hoursInADay) close = quoteBar.Close;
}
_c--;
if(_c == _lookBackHours - (hoursInADay*2)) break;
}
//Calculate Pivot Points for Previous day
PP = Math.Round((highestHigh + lowestLow + close)/3,5) ;
S1 = Math.Round(PP - (0.382M * (highestHigh - lowestLow)),5);
S2 = Math.Round((PP) - (0.618M * (highestHigh - lowestLow)),5);
S3 = Math.Round((PP) - (1M * (highestHigh - lowestLow)),5);
R1 = Math.Round((PP) + (0.382M * (highestHigh - lowestLow)),5);
R2 = Math.Round((PP) + (0.618M * (highestHigh - lowestLow)),5);
R3 = Math.Round((PP) + (1M * (highestHigh - lowestLow)),5);
//Calculate Pivot Points for Previous day
oldPP = Math.Round((highestHigh + lowestLow + close)/3,5) ;
oldS1 = Math.Round(oldPP - (0.382M * (oldhighestHigh - oldlowestLow)),5);
oldS2 = Math.Round((oldPP) - (0.618M * (oldhighestHigh - oldlowestLow)),5);
oldS3 = Math.Round((oldPP) - (1M * (oldhighestHigh - oldlowestLow)),5);
oldR1 = Math.Round((oldPP) + (0.382M * (oldhighestHigh - oldlowestLow)),5);
oldR2 = Math.Round((oldPP) + (0.618M * (oldhighestHigh - oldlowestLow)),5);
oldR3 = Math.Round((oldPP) + (1M * (oldhighestHigh - oldlowestLow)),5);
return;
}
public void Score(){
//Generate score and set to score
return;
}
public void UpdateScore(IEnumerable quoteBarHistory)
{
int daysToGet = 20;
//Sets the % change for the days
for (int x = 1; x <= 20; x++){
_dayChange[x] = GetDayChange(x, quoteBarHistory);
}
//Set 5 day Linear Regression
days2 = _dayChange[1] + _dayChange[2];
days3 = days2 + _dayChange[3];
days4 = days3 + _dayChange[4];
days5 = days4 + _dayChange[5];
//Get Average
_average = 0;
for(int x = 1; x <=20; x++){
_average = _average + Math.Abs(_dayChange[x]);
}
_average = _average/20;
//Set States to get Score
//Steady Down Trend
if(days2 > -1M*_average && days2 < 0){
_states[1] = -1;
}
else{
_states[1] = 0;
}
if(days3 <0 && days3 > -1M*_average){
_states[2] = -1;
}
else{
_states[2] = 0;
}
if(days4 <0 && days4 > -1M*_average){
_states[3] = -1;
}
else{
_states[3] = 0;
}
if(days5 <0 && days5 > -1M*_average){
_states[4] = -1;
}
else{
_states[4] = 0;
}
//Steady Up Trend
if(days2>0 && days2 < _average){
_states[5] = 1;
}
else{
_states[5] = 0;
}
if(days3>0 && days3 < _average){
_states[6] = 1;
}
else{
_states[6] = 0;
}
if(days4>0 && days4 < _average){
_states[7] = 1;
}
else{
_states[7] = 0;
}
if(days5>0 && days5 < _average){
_states[8] = 1;
}
else{
_states[8] = 0;
}
//Flat Market
if(days2 > 0){
_states[9] = 1;
}
else {
_states[9] = 0;
}
if(days3 > 0){
_states[10] = 1;
}
else {
_states[10] = 0;
}
if(days4 > 0){
_states[11] = 1;
}
else {
_states[11] = 0;
}
if(days5 > 0){
_states[12] = 1;
}
else {
_states[12] = 0;
}
//Downtrend Reversal
if(days2 > (-3 *_average) && days2 < (-1*_average)){
_states[13] = 1;
}
else {
_states[13] = 0;
}
if(days3 > (-3 *_average) && days3 < (-1*_average)){
_states[14] = 1;
}
else {
_states[14] = 0;
}
if(days4 > (-3 *_average) && days4 < (-1*_average)){
_states[15] = 1;
}
else {
_states[15] = 0;
}
if(days5 > (-3 *_average) && days5 < (-1*_average)){
_states[16] = 1;
}
else {
_states[16] = 0;
}
//Uptrend Reversal
if(days2<3*_average && days2>_average){
_states[17] = -1;
}
else{
_states[17] = 0;
}
if(days3<3*_average && days3>_average){
_states[18] = -1;
}
else{
_states[18] = 0;
}
if(days4<3*_average && days4>_average){
_states[19] = -1;
}
else{
_states[19] = 0;
}
if(days5<3*_average && days5>_average){
_states[20] = -1;
}
else{
_states[20] = 0;
}
//Super Uptrend
if(days2>3*_average){
_states[21] = 4;
}
else {
_states[21] = 0;
}
if(days3>3*_average){
_states[22] = 4;
}
else {
_states[22] = 0;
}
if(days4>3*_average){
_states[23] = 4;
}
else {
_states[23] = 0;
}
if(days5>3*_average){
_states[24] = 4;
}
else {
_states[24] = 0;
}
//Super Downtrend
if(days2 < -3*_average){
_states[25] = -4;
}
else{
_states[25] = 0;
}
if(days3 < -3*_average){
_states[26] = -4;
}
else{
_states[26] = 0;
}
if(days4 < -3*_average){
_states[27] = -4;
}
else{
_states[27] = 0;
}
if(days5 < -3*_average){
_states[28] = -4;
}
else{
_states[28] = 0;
}
//_scenerios
if(GetSum(9,12,_states)==2){
_scenerios[1] = 1;
}
else{
_scenerios[1] = 0;
}
//Scene 2
if(_states[13]==1 && _states[14] ==1 && _states[15] == 1){
_scenerios[2] = 1;
}
else{
_scenerios[2] = 0;
}
//Scene 3
if(_states[13]==1 && _states[15] ==1 && _states[16] == 1){
_scenerios[3] = 1;
}
else{
_scenerios[3] = 0;
}
//Scene 4
if(_states[17]==-1 && _states[18]==-1 && _states[19]== -1){
_scenerios[4] = -1;
}
else{
_scenerios[4] = 0;
}
//Scene 5
if(_states[17]==-1 && _states[19]==-1 && _states[20]== -1){
_scenerios[5] = -1;
}
else{
_scenerios[5] = 0;
}
//Scene 6
if(GetSum(2,5,_scenerios)==0 && GetSum(5,7,_states)==3){
_scenerios[6] = 1;
}
else{
_scenerios[6] = 0;
}
//Scene 7
if(GetSum(2,5,_scenerios)==0 && GetSum(6,8,_states)==3){
_scenerios[7] = 1;
}
else{
_scenerios[7] = 0;
}
//Scene 8
if(GetSum(2,5,_scenerios)==0 && _states[5]==1 && _states[7]==1 && _states[8]==1){
_scenerios[8] = 1;
}
else{
_scenerios[8] = 0;
}
//Scene 9
if(GetSum(2,5,_scenerios)==0 && GetSum(1,3,_states)==-3){
_scenerios[9] = -1;
}
else{
_scenerios[9] = 0;
}
//Scene 10
if(GetSum(2,5,_scenerios)==0 && GetSum(2,4,_states)==-3){
_scenerios[10] = -1;
}
else{
_scenerios[10] = 0;
}
//Scene 11
if(GetSum(2,5,_scenerios)==0 && _states[1]==-1 && _states[2]==-1 && _states[4]==-1){
_scenerios[11] = -1;
}
else{
_scenerios[11] = 0;
}
//Scene 12
if(GetSum(21,24,_states)>0){
_scenerios[12] = 4;
}
else{
_scenerios[12] = 0;
}
//Scene 13
if(GetSum(25,28,_states)<0){
_scenerios[13] = -4;
}
else{
_scenerios[13] = 0;
}
//Scene 14
if(GetSum(1,13,_scenerios)==0 && GetSum(1,4,_states)<-1){
_scenerios[14] = -1;
}
else{
_scenerios[14] = 0;
}
//Scene 15
if(GetSum(1,13,_scenerios)==0 && GetSum(5,8,_states)>1){
_scenerios[15] = 1;
}
else{
_scenerios[15] = 0;
}
//Scene 16
if(GetSum(1,15,_scenerios)==0){
_scenerios[16] = GetSum(1,8,_states)+GetSum(13,28,_states);
}
else{
_scenerios[16] = 0;
}
//Score
score = GetSum(2,16,_scenerios);
}
private int GetSum(int start, int end, int[] list){
int sum = 0;
for(int i = start; i <= end; i++){
sum += list[i];
}
return(sum);
}
private decimal GetDayChange(int day, IEnumerable quoteBarHistory){
decimal change = 0;
int _counter = _lookBackHours;
foreach (QuoteBar quoteBar in quoteBarHistory)
{
//day 1
if(day == 1){
if(_counter == _lookBackHours){
close = quoteBar.Close;
}
if(_counter == _lookBackHours - hoursInADay+1){
open = quoteBar.Open;
change = Math.Round((close/open)-1M,4);
break;
}
}
//All other Days
if(_counter == _lookBackHours - (hoursInADay*(day - 1))){
close = quoteBar.Close;
}
if(_counter == _lookBackHours - (hoursInADay*day)+1){
open = quoteBar.Open;
change = Math.Round((close/open)-1M,4);
}
_counter--;
}
return(change);
}
}
}