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);
}
}
}
Crash Overide
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!